如何确定Swift enum中的案例数?

(我希望避免手动枚举所有值,或者如果可能的话使用旧的“enum_count技巧”。)


当前回答

创建如下答案所示的静态allValues数组

enum ProductCategory : String {
     case Washers = "washers", Dryers = "dryers", Toasters = "toasters"

     static let allValues = [Washers, Dryers, Toasters]
}

...

let count = ProductCategory.allValues.count

当您希望枚举值时,这也很有用,并且适用于所有Enum类型

其他回答

只是想共享一个解决方案时,你有一个枚举与相关的值。

enum SomeEnum {
  case one
  case two(String)
  case three(String, Int)
}

CaseIterable不会自动提供allcase。 我们不能为枚举提供像Int这样的原始类型来计算case计数。

我们能做的是使用开关的功率和通过关键字。

extension SomeEnum {
  static var casesCount: Int {
    var sum = 0

    switch Self.one { // Potential problem
       case one:
         sum += 1
         fallthrough

       case two:
         sum += 1
         fallthrough

       case three:
         sum += 1
    }

    return sum
  }
}

现在你可以说someenume。casescount。

备注:

赛尔夫开关还是有问题。一个{…,我们硬编码了第一个案例。您可以很容易地破解这个解决方案。但我只是将它用于单元测试,所以这不是问题。 如果您经常需要在枚举中获得带有关联值的case计数,请考虑代码生成。

如果实现不反对使用整数enum,你可以添加一个额外的成员值Count来表示枚举中的成员数量-参见下面的例子:

enum TableViewSections : Int {
  case Watchlist
  case AddButton
  case Count
}

现在,您可以通过调用TableViewSections.Count.rawValue来获取枚举中的成员数量,在上面的例子中,它将返回2。

当你在switch语句中处理枚举时,确保在遇到Count成员时抛出断言失败:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  let currentSection: TableViewSections = TableViewSections.init(rawValue:section)!
  switch(currentSection) {
  case .Watchlist:
    return watchlist.count
  case .AddButton:
    return 1
  case .Count:
    assert(false, "Invalid table view section!")
  }
}

这是次要的,但我认为一个更好的O(1)解决方案将是以下(只有当你的enum是Int从x开始,等等):

enum Test : Int {
    case ONE = 1
    case TWO
    case THREE
    case FOUR // if you later need to add additional enums add above COUNT so COUNT is always the last enum value 
    case COUNT

    static var count: Int { return Test.COUNT.rawValue } // note if your enum starts at 0, some other number, etc. you'll need to add on to the raw value the differential 
}

我仍然认为当前选择的答案是所有枚举的最佳答案,除非您正在使用Int,否则我推荐这个解决方案。

Xcode 10更新

在枚举中采用CaseIterable协议,它提供了一个静态的allCases属性,其中包含所有枚举案例作为一个集合。只需使用它的count属性就可以知道枚举有多少个case。

请看马丁的答案(为他的答案而不是我的答案投票)


警告:下面的方法似乎不再有效。

我不知道有任何通用方法来计算枚举案例的数量。但是,我注意到枚举案例的hashValue属性是递增的,从零开始,顺序由声明案例的顺序决定。最后一个枚举加1的哈希值对应的是案例数。

例如,对于这个enum:

enum Test {
    case ONE
    case TWO
    case THREE
    case FOUR

    static var count: Int { return Test.FOUR.hashValue + 1}
}

Count返回4。

我不能说这是一个规则,或者它在未来是否会改变,所以使用你自己的风险:)

扩展Matthieu Riegler的回答,这是一个Swift 3的解决方案,不需要使用泛型,可以很容易地使用枚举类型EnumType.elementsCount调用:

extension RawRepresentable where Self: Hashable {

    // Returns the number of elements in a RawRepresentable data structure
    static var elementsCount: Int {
        var i = 1
        while (withUnsafePointer(to: &i, {
            return $0.withMemoryRebound(to: self, capacity: 1, { return 
                   $0.pointee })
        }).hashValue != 0) {
            i += 1
        }
        return i
}