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

问题描述:

我有以下枚举.

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

我需要以字符串数组的形式获取所有原始值(例如["Pending", "On Hold", "Done"]).

I need to get all the raw values as an array of strings (like so ["Pending", "On Hold", "Done"]).

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

I added this method to the enum.

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

但我收到以下错误.

找不到类型GeneratorOf"的初始化程序,它接受类型为(() -> _)"的参数列表

Cannot find an initializer for type 'GeneratorOf' that accepts an argument list of type '(() -> _)'

有没有更简单、更好或更优雅的方法来做到这一点?

Is there is an easier, better or more elegant way to do this?

适用于 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)
}

对于 Swift <4.2

不,您不能查询 enum 包含的值.请参阅这篇文章.您必须定义一个数组,列出您拥有的所有值.另请查看How to以数组形式获取所有枚举值".


For Swift < 4.2

No, you can't query an enum for what values it contains. See this article. You have to define an array that list all the values you have. Also check out Frank Valbuena's solution in "How to get all enum values as an array".

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