关于ios:在Swift中循环使用枚举值

Looping through enum values in Swift

本问题已经有最佳答案,请猛点这里访问。

是否可以在swift中循环枚举值?或者有什么选择?

我正在阅读苹果的Swift语言指南,我在Enums上遇到了这个例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//  EXPERIMENT
//
//  Add a method to Card that creates a full deck of cards,
//  with one card of each combination of rank and suit.

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return"The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
        case .Spades:
            return"spades"
        case .Hearts:
            return"hearts"
        case .Diamonds:
            return"diamonds"
        case .Clubs:
            return"clubs"
        }
    }
}

enum Rank: Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
        case .Ace:
            return"ace"
        case .Jack:
            return"jack"
        case .Queen:
            return"queen"
        case .King:
            return"king"
        default:
            return String(self.toRaw())
        }
    }
}

摘自:苹果公司。"Swift编程语言。"iBooks。网址:https://itun.es/us/jeuh0.l

我尝试过以下方法,但是文档说swift中的枚举并没有像c中那样被分配给底层的整数值,所以我可能找错了树。

有没有更好的方法来解决这个问题?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func deck() -> Card[]{
    var deck: Card[]
    for s in Suit {
        for r in Rank {
            deck += Card(rank: r, suit: s)
        }
    }
    return deck
}

func deck2() -> Card[]{
    var deck: Card[]
    for var s: Suit = .Spades; s <= .Clubs; s++ {
        for var r: Rank = .Ace; r <= .King; r++ {
            deck += Card(rank: r, suit: s)
        }
    }
    return deck
}


还有别的办法吗?当然。更好的办法是,由你来决定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func generateDeck() -> Card[]
{
    let ranksPerSuit = 13
    var deck = Card[]()

    for index in 0..52
    {
        let suit = Suit.fromRaw(index / ranksPerSuit)
        let rank = Rank.fromRaw(index % ranksPerSuit + 1)

        let card = Card(rank: rank!, suit: suit!)
        deck.append(card)
    }

    return deck
}

let deck = generateDeck()

for card : Card in deck { println("\(card.description)") }

要使用它,您需要确保RankSuit枚举都将Int用于它们的类型定义(例如:enum Rank : Int)。

Rank.Ace等于1,第一个Suit等于0

如果您希望循环类似于现有代码,那么仍然应该使EnumsInt类型,这样您就可以使用Rank.King.toRaw()等。

Apple文档指出,枚举不限于"简单的整数值",但如果您希望这样做,当然可以这样做。

更新

来自@jay imerman评论的想法,适用于Swift 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
extension Rank: CaseIterable {}
extension Suit: CaseIterable {}

func generateDeck() -> [Card] {
    var deck = [Card]();

    Rank.allCases.forEach {
        let rank = $0

        Suit.allCases.forEach {
            let suit = $0

            deck.append(Card(rank: rank, suit: suit))
        }
    }

    return deck;
}