4

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)
}
cfischer
  • 24,452
  • 37
  • 131
  • 214
  • 1
    Enums have to be declared at compile time, therefore you - the developer - know exactly how many cases an enum has. ;-) – vadian Aug 25 '15 at 19:23
  • I have an answer you can refer to here https://stackoverflow.com/a/48960126/5372480 – MkSMC Mar 23 '18 at 20:21

2 Answers2

6

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 {
    // ...
}
Qbyte
  • 12,753
  • 4
  • 41
  • 57
3

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)
}
yshilov
  • 774
  • 1
  • 8
  • 11