2014-06-05 122 views
28

是否有可能在Swift中遍歷枚舉值?或者有什麼選擇?循環遍歷Swift中的枚舉值

我正在通過蘋果的Swift語言指南,我遇到了關於枚舉的這個例子。

// 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()) 
     } 
    } 
} 

摘錄自:蘋果公司「The Swift Programming Language。」iBooks。 https://itun.es/us/jEUH0.l

我試過以下,但文檔中說,在Swift中的枚舉不會像C中那樣分配底層整數值,所以我可能會吠叫錯誤的樹。

有沒有更好的方法來解決這個問題?

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 
} 
+0

@MartinR謝謝,我沒有在我最初的搜索中找到一些原因。 雖然略有差異,但我也在尋找方法來實現構建一副沒有循環卡片的目標,如果可能的話。大概應該讓這個職位更清楚。 – glaslong

+1

好吧,看來Swift沒有一個特別簡單的方法來迭代枚舉成員,而沒有將它們定義爲整數。有點令人失望,但我想我不應該像這樣使用枚舉。 仍然好奇爲什麼他們在書中以這種方式使用它,當字典似乎是這種情況下更好的選擇。 – glaslong

回答

17

還有別的辦法嗎?當然。它是更好,這是由你來決定:

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

如果你想循環類似於你現有的代碼,你仍然應該使你的枚舉Int類型,所以你可以使用Rank.King.toRaw()等。

蘋果文檔指出,枚舉並不侷限於「簡單的整數值」,但當然可以是,如果你希望他們是。

+0

這是我見過的更好的答案之一。它很乾淨,簡短,並且不會嘗試將枚舉排除在外。謝謝! – glaslong

+1

我不知道,我不相信。我的問題在於它對迭代限制進行了硬編碼,而不是從枚舉中推斷出它們。我想知道,在代碼中如何獲得枚舉的限制/邊界,並在for循環中使用... –

+2

我發現了一個非常優雅的答案張貼由sdduursma對這個問題在同一個http://stackoverflow.com/questions/24007461 /如何枚舉-enum-with-string-type –