Introspection and iteration on an Enum

半世苍凉 提交于 2019-12-04 09:20:34

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)
}

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 {
    // ...
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!