在 Swift 中循环遍历枚举值

19 浏览
0 Comments

在 Swift 中循环遍历枚举值

这个问题已经有了答案

如何在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())
        }
    }
}

摘自:Apple Inc. “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
}

admin 更改状态以发布 2023年5月24日
0
0 Comments

还有其他方法吗?当然。它是否更好,取决于您的决定:

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 case应该等于0

如果您想要循环类似于您现有的代码,您仍应使您的枚举Int类型,这样您就可以使用Rank.King.toRaw()等。

苹果文档指出,枚举并不限于“仅仅是整数值”,但如果您希望它们是这样,它们当然可以是。

更新

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

0