Consider if there is a `enum` type of poker suit and rank. We want to enumerate both to get a whole set of poker.

The suit and rank are defined as below respectively:

``````enum Suit: String {
case Spades = "Spades"
case Hearts = "Hearts"
case Clubs = "Clubs"
case Diamonds = "Diamonds"
}

enum Rank: Int, Printable {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
var description: String {
switch self {
case .Ace:
return "A"
case .Jack:
return "J"
case .Queen:
return "Q"
case .King:
return "K"
default:
return String(self.rawValue)
}
}
}
``````

The most easy way should be looping in the two `enum`: first get a possible `Suit` enum value, and then loop in `Rank` to generate 13 cards.

In some other language, we could enumerate an enum type directly, or there might be a `values` property in the type for us to loop. The code might be like this:

``````for suit in Suit.values {
for rank in Rank.values {
// ...
}
}
``````

However, it does not apply in Swift. The reason is in Swift `enum`, we can contain some extra data (the `case Some(T)`). It cannot be expressed in a `for...in` statement without losing type information. In the example case, there is no such enum item with parameter, so we can construct a enumerable enum by using static property.

Create a protocol for it first:

``````protocol EnumeratableEnumType {
static var allValues: [Self] {get}
}
``````

And make `Suit` and `Rank` conform this protocol:

``````enum Suit: String, EnumeratableEnumType {

//...

static var allValues: [Suit] {
return [.Spades, .Hearts, .Clubs, .Diamonds]
}
}

enum Rank: Int, Printable, EnumeratableEnumType {

//...

static var allValues: [Rank] {
return [.Ace, .Two, .Three,
.Four, .Five, .Six,
.Seven, .Eight, .Nine,
.Ten, .Jack, .Queen, .King]
}
}
``````

After the `allValues` property implemented, we could follow our first idea:

``````for suit in Suit.allValues {
for rank in Rank.allValues {
print("\(suit.rawValue) \(rank)")
}
}

// Output
// Spades A
// Spades 2
// Spades 3
// ...
// Diamonds K
``````