【问题标题】:Looping through enum values in Swift [duplicate]在 Swift 中遍历枚举值 [重复]
【发布时间】:2014-07-26 12:41:26
【问题描述】:

是否可以在 Swift 中循环遍历枚举值?或者有什么替代方法?

我正在阅读 Apple 的 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())
        }
    }
}

摘自:Apple Inc. “Swift 编程语言”。电子书。 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
}

【问题讨论】:

  • @MartinR 谢谢,由于某种原因,我在最初的搜索中没有找到它。虽然略有不同,但如果可能的话,我也在寻找方法来实现构建卡片组而不循环的目标。可能应该在帖子中更清楚地说明这一点。
  • 好吧,看起来 Swift 没有一种特别简单的方法来迭代枚举成员而不将它们定义为整数。有点令人失望,但我想我不应该使用这样的枚举。仍然很好奇为什么他们在书中这样使用它,而字典似乎是这种情况下更好的选择。

标签: ios swift loops enums


【解决方案1】:

还有其他方法吗?当然。是否更好,由你决定:

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() 等。

Apple 文档指出,枚举不限于“简单的整数值”,但如果您愿意,当然可以。

更新

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

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;
}

【讨论】:

  • 这是我见过的更好的答案之一。它干净,简短,并且不会尝试放弃枚举以获取其他内容。谢谢!
  • 我不知道,我不相信。我的问题是它对迭代限制进行了硬编码,而不是从枚举中推断出来。我想知道,在代码中如何获取枚举的限制/边界并在 for 循环中使用它...
  • 我发现 sdduursma 在同一个stackoverflow.com/questions/24007461/… 上就这个问题发表了一个非常优雅的答案
  • stackoverflow 代码着色不适用于最后一行字符串表达式中的变量 :)
  • 你必须补偿索引中的 0 这样设置 -> 用于 0...51 中的索引
猜你喜欢
  • 2010-12-12
  • 2011-09-04
  • 2015-08-13
  • 2015-01-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多