2014-06-05 124 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 –