Initialize all using an executed-one-time-only closure and AnyGenerator
@vacawama showed how to initialize the all array in a generalized manner using an executed-one-time-only closure in combination with the failable init(rawValue:) initialer of enum's. A slight variation of the method in the fore mentioned answer is to exchange the explicit while loop and array appending with an AnyGenerator:
enum Type: Int {
case A = 0, B, C, D, E, F, G, H
static let all: [Type] = {
var rValue = 0
return AnyGenerator<Type> {
defer { rValue += 1 }
return Type(rawValue: rValue)
}.map{$0}
}()
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
This works under the condition that rawValue's are simply ++ increasing (0, 1, 2, ...).
Initialize all by conforming the enum to SequenceType
As another alternative, since your rawValue's are integer-wise sequential (++), you could let your enum conform to SequenceType, in which case the array of all cases can be easily generated simply by using .map
enum Type: Int, SequenceType {
case A = 0, B, C, D, E, F, G, H
init() { self = A } // Default (first) case intializer
/* conform Type to SequenceType (here: enables only
simple (self.rawValue)...last traversing) */
func generate() -> AnyGenerator<Type> {
var rValue = self.rawValue
return AnyGenerator {
defer { rValue += 1 }
return Type(rawValue: rValue)
}
}
/* use the fact that Type conforms to SequenceType to neatly
initialize your static all array */
static let all = Type().map { $0 }
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
Applying this conformance only to initialize the static all array is possibly overkill, but a plausible alternative in case you'd like to be able to able to use other aspects of your enum conforming to SequenceType
for typeCase in Type() {
// treat each type ...
print(typeCase, terminator: " ")
} // A B C D E F G H
for caseFromEAndForward in Type.E {
print(caseFromEAndForward, terminator: " ")
} // E F G H
Using flatMap to initialize cases based on a range of rawValue's
Finally, as a variation of @appzYourLife neat solution, in case you have very many cases, you can use a flatMap operation on the range of rawValue's to initialize the static allValues array, e.g.
enum Type: Int {
case A = 0, B, C, D, E, F, G, H
static let all = (A.rawValue...H.rawValue)
.flatMap{ Type(rawValue: $0) }
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
There's, however, not really any practical use for this method as the general size methods (@vacawama:s or the SequenceType above) would always be preferable for enums of many cases. The possibly use case I can see for this is if the rawValue's of the different cases are sequential but not simply by ++, e.g. if the rawValue's are used for some bitmasking
// ...
case A = 0, B = 2, C = 4, D = 8, E = 16, F = 32, G = 64, H = 128
The method above would use a method of brute-forcing through the range of rawValue's, where a minority will actually correspond to actual cases. Somewhat wasteful, but since it's a one-time static initialization, that shouldn't really be an issue.
enumas theTypeis reserved for something else in a Swift class; and the class's name should be capitalised as well, likeSomeClass.