607 votes

Comment énumérer une énumération avec un type String?

 enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
        case .Spades:
            return "spaces"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
}
 

Par exemple, comment puis-je faire quelque chose comme:

 for suit in Suit {
  // do something with suit
}
 

539voto

rougeExciter Points 1253

Ce post est pertinent ici http://www.swift-studies.com/blog/2014/6/10/enumerating-enums-in-swift

Essentiellement, la solution proposée est

 enum ProductCategory : String {
     case Washers = "washers", Dryers = "dryers", Toasters = "toasters"

     static let allValues = [Washers, Dryers, Toasters]
}

for category in ProductCategory.allValues{
     //Do something
}
 

135voto

sdduursma Points 140

Les autres solutions de travail , mais ils ont tous faire des hypothèses, par exemple, le nombre de classements possibles et les costumes, ou ce que le premier et le dernier rang. Vrai, la mise en page d'un jeu de cartes ne va pas probablement beaucoup de changement dans un avenir prévisible. En général, cependant, il est plus propre d'écrire du code qui fait que peu d'hypothèses possible. Ma solution:

J'ai ajouté une crue de type pour le costume enum, donc je peux l'utiliser en combinaison(rawValue:) pour accéder à la fonction de cas:

enum Suit: Int {
    case Spades, Hearts, Diamonds, Clubs
    //...

Ci-dessous la mise en œuvre de la Carte createDeck() la méthode. init(rawValue:) est un failable initialiseur et renvoie une option. Par déballage et vérification de sa valeur dans les deux alors que les états, il n'y a pas besoin de supposer que le nombre de Grade ou de fonction de cas:

func createDeck() -> [Card] {

    var deck = [Card]()

    var n = 1
    while let rank = Rank(rawValue: n) {

        var m = 0
        while let suit = Suit(rawValue: m) {
            deck.append(Card(rank: rank, suit: suit))
            m++
        }
        n++
    }

    return deck
}

26voto

RndmTsk Points 39

Vous ne pouvez pas parcourir une énumération tant que vous n'avez pas implémenté le protocole ForwardIndex .

Le protocole ForwardIndex nécessite que vous définissiez une fonction successor() pour parcourir les éléments.

 enum Rank: Int, ForwardIndex {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King

    // ... other methods

    // Option 1 - Figure it out by hand
    func successor() -> Rank {
        switch self {
            case .Ace:
              return .Two
            case .Two:
              return .Three

            // ... etc.

            default:
              return .King
        }
    }

    // Option 2 - Define an operator!
    func successor() -> Rank {
        return self + 1
    }
}

// NOTE: The operator is defined OUTSIDE the class
func + (left: Rank, right: Int) -> Rank {
    // I'm using to/from raw here, but again, you can use a case statement
    // or whatever else you can think of

    return left == .King ? .King : Rank.fromRaw(left.toRaw() + right)!
}
 

L'itération sur une plage ouverte ou fermée ( ..< ou ... ) appelera en interne la fonction successor() qui vous permet d'écrire ceci:

 // Under the covers, successor(Rank.King) and successor(Rank.Ace) are called to establish limits
for r in Rank.Ace...Rank.King {
    // Do something useful
}
 

17voto

Alfa07 Points 795

En principe, il est possible de le faire de cette façon en supposant que vous n'utilisez pas l'affectation de valeurs brutes pour les cas d'enum:

 enum RankEnum: Int {
  case Ace
  case One
  case Two
}

class RankEnumGenerator : Generator {
  var i = 0
  typealias Element = RankEnum
  func next() -> Element? {
    let r = RankEnum.fromRaw(i)
    i += 1
    return r
  }
}

extension RankEnum {
  static func enumerate() -> SequenceOf<RankEnum> {
    return SequenceOf<RankEnum>({ RankEnumGenerator() })
  }
}

for r in RankEnum.enumerate() {
  println("\(r.toRaw())")
}
 

2voto

gleb vodovozov Points 1

Je l'ai fait à l'aide calculée de la propriété, qui retourne un tableau de toutes les valeurs (merci pour ce post http://natecook.com/blog/2014/10/loopy-random-enum-ideas/). Cependant, il utilise aussi int brut-valeurs, mais je n'ai pas besoin de répéter tous les membres de l'énumération dans biens distincts.

Mise à JOUR de Xcode 6.1 un peu changé d'une façon comment obtenir enum membre à partir de la valeur brute, donc, je fixe la liste. Également fixé petite erreur de mal avec la première valeur brute

enum ValidSuits:Int{
    case Clubs=0, Spades, Hearts, Diamonds
    func description()->String{
        switch self{
        case .Clubs:
            return "♣︎"
        case .Spades:
            return "♠︎"
        case .Diamonds:
            return "♦︎"
        case .Hearts:
            return "♥︎"
        }
    }

    static var allSuits:[ValidSuits]{
        return Array(
            SequenceOf {
                () -> GeneratorOf<ValidSuits> in
                var i=0
                return GeneratorOf<ValidSuits>{
                    return ValidSuits(rawValue: i++)
                }
            }
        )
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X