2014-06-05 12 views
28

Czy można przeliczyć wartości wyliczenia w Swift? Albo jaka jest alternatywa?Zapętlenie wartości wyliczeniowych w Swift

Pracuję z przewodnikiem po języku Apple firmy Swift i natknąłem się na ten przykład w wyliczeniach.

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

Fragment: Apple Inc. "Język programowania Swift." IBooks. https://itun.es/us/jEUH0.l

Próbowałem następujące, ale docs mówi, że wyliczenia w Swift nie są przypisane do wartości całkowitych, takich jak w C, więc prawdopodobnie szczeka niewłaściwe drzewa.

Czy istnieje lepszy sposób rozwiązania tego problemu?

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 Dzięki, nie znalazłem tego w moim początkowym wyszukiwaniu z jakiegoś powodu. Niewielka różnica, ale szukam również sposobów na osiągnięcie celu, jakim jest zbudowanie talii kart bez pętli, jeśli to możliwe. Prawdopodobnie powinien to uczynić bardziej zrozumiałym w poście. – glaslong

+1

Cóż, wygląda na to, że Swift nie ma szczególnie łatwego sposobu na iterowanie po elementach enum bez definiowania ich jako liczby całkowite. Trochę rozczarowujące, ale przypuszczam, że i tak nie powinienem używać takich wyliczeń. Ciągle ciekawi, dlaczego użyli go w ten sposób w książce, gdy słownik wydaje się znacznie lepszym wyborem dla tego scenariusza. – glaslong

Odpowiedz

17

Czy istnieje inny sposób? Pewnie. Czy lepiej, to do ciebie, aby zdecydować:

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)") } 

Aby to wykorzystać, trzeba się upewnić, że Rank i Suit stałe teksty używają Int dla ich definicji typu (np enum Rank : Int).

Rank.Ace powinien być równy 1, a pierwszy przypadek Suit powinien być równy 0.

Jeśli chcesz używać pętli podobnej do istniejącego kodu, nadal powinieneś wykonywać typy enumeratorów Int, aby móc używać Rank.King.toRaw() i tym podobnych.

Dokumentacja Apple stwierdza, że ​​wyliczenia nie ograniczają się do bycia "po prostu wartościami całkowitymi", ale z pewnością mogą być, jeśli ich chcesz.

+0

To jedna z lepszych odpowiedzi, jakie widziałem. Jest czysty, krótki i nie próbuje porzucić wyrażeń na coś innego. Dziękuję Ci! – glaslong

+1

Nie wiem, nie jestem przekonany. Mój problem polega na tym, że twardo koduje limity iteracji, zamiast wywnioskować je z wyliczeń. Chcę wiedzieć, w kodzie, w jaki sposób uzyskać limity/ograniczenia wyliczenia i użyć, że w pętli for ... –

+2

Znalazłem bardzo elegancka odpowiedź wysłana przez sdduursma na to pytanie na tym samym http://stackoverflow.com/questions/24007461/how-to-enumerate-an-enum-with-string-type –

Powiązane problemy