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プログラミング言語。” 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
}
別の方法はありますか?承知しました。 better、それはあなたが決めることです:
_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)") }
_
これを使用するには、Rank
とSuit
の両方の列挙型が、その型定義にInt
を使用していることを確認する必要があります(例:_enum Rank : Int
_)。
_Rank.Ace
_は_1
_と等しく、最初のSuit
ケースは_0
_と等しくなければなりません。
既存のコードと同様にループしたい場合は、Rank.King.toRaw()
などを使用できるように、列挙型をInt
型にする必要があります。
Appleのドキュメントでは、列挙型は「単純な整数値」に制限されているわけではありませんが、希望する場合は確実に指定できます。
[〜#〜] update [〜#〜]
@ 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;
}
_