将所有枚举值作为数组获取

Isu*_*uru 71 arrays enums swift

我有以下枚举.

enum EstimateItemStatus: Printable {
    case Pending
    case OnHold
    case Done

    var description: String {
        switch self {
        case .Pending: return "Pending"
        case .OnHold: return "On Hold"
        case .Done: return "Done"
        }
    }

    init?(id : Int) {
        switch id {
        case 1:
            self = .Pending
        case 2:
            self = .OnHold
        case 3:
            self = .Done
        default:
            return nil
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要将所有原始值作为字符串数组(如此["Pending", "On Hold", "Done"]).

我将此方法添加到枚举中.

func toArray() -> [String] {
    var n = 1
    return Array(
        GeneratorOf<EstimateItemStatus> {
            return EstimateItemStatus(id: n++)!.description
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误.

无法为类型为'(( - - > _)'的类型'GeneratorOf'找到初始值设定项

我无法弄清楚如何解决这个问题.有帮助吗?或者请告诉我是否有更简单/更好/更优雅的方式来做到这一点.

谢谢.

Cod*_*ent 105

对于Swift 4.2(Xcode 10)及更高版本

有一个CaseIterable协议:

enum EstimateItemStatus: String, CaseIterable {
    case pending = "Pending"
    case onHold = "OnHold"
    case done = "Done"

    init?(id : Int) {
        switch id {
        case 1: self = .pending
        case 2: self = .onHold
        case 3: self = .done
        default: return nil
        }
    }
}

for value in EstimateItemStatus.allCases {
    print(value)
}
Run Code Online (Sandbox Code Playgroud)

对于Swift <4.2

不,您无法查询enum其包含的值.看到这篇文章.您必须定义一个列出所有值的数组.还可以看看Frank Valbuena的聪明解决方案.

enum EstimateItemStatus: String {
    case Pending = "Pending"
    case OnHold = "OnHold"
    case Done = "Done"

    static let allValues = [Pending, OnHold, Done]

    init?(id : Int) {
        switch id {
        case 1:
            self = .Pending
        case 2:
            self = .OnHold
        case 3:
            self = .Done
        default:
            return nil
        }
    }
}

for value in EstimateItemStatus.allValues {
    print(value)
}
Run Code Online (Sandbox Code Playgroud)

  • upvoting为allValues部分,但不确定对枚举类型为String但使用Int初始化的感觉. (3认同)

Sh_*_*han 26

Swift 4.2引入了一个名为的新协议CaseIterable

enum Fruit : CaseIterable {
    case apple , apricot , orange, lemon
}
Run Code Online (Sandbox Code Playgroud)

当你符合时,你可以从这样的enum案例中得到一个数组

for fruit in Fruit.allCases {
    print("I like eating \(fruit).")
}
Run Code Online (Sandbox Code Playgroud)


Fra*_*ena 17

还有另一种方法,至少在编译时是安全的:

enum MyEnum {
    case case1
    case case2
    case case3
}

extension MyEnum {
    static var allValues: [MyEnum] {
        var allValues: [MyEnum] = []
        switch (MyEnum.case1) {
        case .case1: allValues.append(.case1); fallthrough
        case .case2: allValues.append(.case2); fallthrough
        case .case3: allValues.append(.case3)
        }
        return allValues
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这适用于任何枚举类型(RawRepresentable与否)以及如果添加新案例,那么您将收到一个好的编译器错误,因为这会强制您使其保持最新状态.

  • 非正统,但它有效,并且如果您修改枚举案例,它会警告您。聪明的解决方案! (2认同)

Vla*_*kov 17

enum EstimateItemStatus: String, CaseIterable {
  case pending = "Pending"
  case onHold = "OnHold"
  case done = "Done"

  static var statusList: [String] {
    return EstimateItemStatus.allCases.map { $0.rawValue }
  }
}
Run Code Online (Sandbox Code Playgroud)

[“待定”、“暂停”、“完成”]


Dan*_*uta 12

我找到了这个代码:

protocol EnumCollection : Hashable {}


extension EnumCollection {

    static func cases() -> AnySequence<Self> {
        typealias S = Self
        return AnySequence { () -> AnyIterator<S> in
            var raw = 0
            return AnyIterator {
                let current : Self = withUnsafePointer(to: &raw) { $0.withMemoryRebound(to: S.self, capacity: 1) { $0.pointee }
                }
                guard current.hashValue == raw else { return nil }
                raw += 1
                return current
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用:

enum YourEnum: EnumCollection { //code }

YourEnum.cases()
Run Code Online (Sandbox Code Playgroud)

从YourEnum返回案例列表

  • 这打破了XCode 10(无论Swift版本)作为枚举的hashValue不再增量但随机,打破了机制.执行此操作的新方法是升级到Swift 4.2并使用CaseIterable (5认同)

max*_*ell 12

将CaseIterable协议添加到枚举:

enum EstimateItemStatus: String, CaseIterable {
    case pending = "Pending"
    case onHold = "OnHold"
    case done = "Done"
}
Run Code Online (Sandbox Code Playgroud)

用法:

let values: [String] = EstimateItemStatus.allCases.map { $0.rawValue }
//["Pending", "OnHold", "Done"]
Run Code Online (Sandbox Code Playgroud)

  • +1。应该是 Swift 5 后接受的答案。您还可以在枚举内执行 `static let value: [String] ...` 以使其更好。 (4认同)

吖奇说*_*HUō 6

要获得出于功能目的的列表,请使用EnumName.allCases返回数组的表达式,例如

EnumName.allCases.map{$0.rawValue} 
Run Code Online (Sandbox Code Playgroud)

给定一个字符串列表 EnumName: String, CaseIterable

注意:使用allCases代替AllCases()。