Reputation: 24912
Is it possible to programatically find out how many "cases" an Enum has in Swift 2 and iterate over them?
This code doesn't compile, but it gives yo an idea of what I'm trying to achieve:
enum HeaderStyles{
case h1
case h2
case h3
}
for item in HeaderStyles{
print(item)
}
Upvotes: 4
Views: 1273
Reputation: 13263
The easiest way to iterate over all cases is to make a computed property which returns an Array
of them:
enum SomeEnum {
case Zero, One, Two
static var allCases: [SomeEnum] {
return [.Zero, .One, .Two]
}
}
If you want an automatic array you could use Int
as rawValue so you don't have to change any code if you add an additional case
:
Swift 3/4: ++
and --
were removed and anyGenerator
was renamed to AnyIterator
enum SomeEnum: Int {
case Zero, One, Two
static var allCases: [SomeEnum] {
var i = 0
return Array(AnyIterator{
let newEnum = SomeEnum(rawValue: i)
i += 1
return newEnum
})
}
}
Swift 2
enum SomeEnum: Int {
case Zero, One, Two
static var allCases: [SomeEnum] {
var i = 0
return Array(anyGenerator{ SomeEnum(rawValue: i++) })
}
}
In both cases you would use it like this:
for num in SomeEnum.allCases {
// ...
}
Upvotes: 6
Reputation: 794
You can write a generic struct that provide that iteration ability. In example below the enum raw values must start with 0 (it does it by default) and have no gaps between raw values (can't have raw values such as 0,1,2,3,5 -- 4 is missing)
public struct EnumGenerator<T> : GeneratorType, SequenceType {
private let enumInit: Int -> T?
private var i: Int = 0
public mutating func next() -> T? { return enumInit(i++) }
public init(_ initFunc: Int -> T?){ self.enumInit = initFunc}
}
enum HeaderStyles:Int{
case h1
case h2
case h3
}
for item in EnumGenerator(HeaderStyles.init){
print(item)
}
Upvotes: 3