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

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


当前回答

enum EnumNameType: Int {
    case first
    case second
    case third

    static var count: Int { return EnumNameType.third.rawValue + 1 }
}

print(EnumNameType.count) //3

OR

enum EnumNameType: Int {
    case first
    case second
    case third
    case count
}

print(EnumNameType.count.rawValue) //3

*在Swift 4.2 (Xcode 10)可以使用:

enum EnumNameType: CaseIterable {
    case first
    case second
    case third
}

print(EnumNameType.allCases.count) //3

其他回答

大家好,单元测试呢?

func testEnumCountIsEqualToNumberOfItemsInEnum() {

    var max: Int = 0
    while let _ = Test(rawValue: max) { max += 1 }

    XCTAssert(max == Test.count)
}

这与安东尼奥的解决方案相结合:

enum Test {

    case one
    case two
    case three
    case four

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

在主代码中给你O(1),加上如果有人添加了enum case 5并且没有更新count的实现,你会得到一个失败的测试。

我为自己解决了这个问题,创建了一个协议(EnumIntArray)和一个全局实用函数(EnumIntArray),可以很容易地将“All”变量添加到任何enum(使用swift 1.2)。“all”变量将包含枚举中所有元素的数组,因此您可以使用all。算一算

它只适用于使用Int类型原始值的枚举,但也许它可以为其他类型提供一些启发。

它还解决了我在上面和其他地方读到的“编号差距”和“迭代时间过多”问题。

其思想是将EnumIntArray协议添加到枚举,然后通过调用EnumIntArray函数定义一个“all”静态变量,并为其提供第一个元素(如果编号有间隙,则为最后一个元素)。

因为静态变量只初始化了一次,所以遍历所有原始值的开销只会对程序造成一次冲击。

示例(无空白):

enum Animals:Int, EnumIntArray
{ 
  case Cat=1, Dog, Rabbit, Chicken, Cow
  static var all = enumIntArray(Animals.Cat)
}

示例(有空格):

enum Animals:Int, EnumIntArray
{ 
  case Cat    = 1,  Dog, 
  case Rabbit = 10, Chicken, Cow
  static var all = enumIntArray(Animals.Cat, Animals.Cow)
}

下面是实现它的代码:

protocol EnumIntArray
{
   init?(rawValue:Int)
   var rawValue:Int { get }
}

func enumIntArray<T:EnumIntArray>(firstValue:T, _ lastValue:T? = nil) -> [T]
{
   var result:[T] = []
   var rawValue   = firstValue.rawValue
   while true
   { 
     if let enumValue = T(rawValue:rawValue++) 
     { result.append(enumValue) }
     else if lastValue == nil                     
     { break }

     if lastValue != nil
     && rawValue  >  lastValue!.rawValue          
     { break }
   } 
   return result   
}

为什么要把事情搞得这么复杂?Int enum最简单的计数器是添加:

病例数

最后。和…维奥拉,现在你有计数了,又快又简单

我有一篇博客文章详细介绍了这一点,但只要你的枚举的原始类型是一个整数,你可以这样添加一个计数:

enum Reindeer: Int {
    case Dasher, Dancer, Prancer, Vixen, Comet, Cupid, Donner, Blitzen
    case Rudolph

    static let count: Int = {
        var max: Int = 0
        while let _ = Reindeer(rawValue: max) { max += 1 }
        return max
    }()
}

带索引的Enum

enum eEventTabType : String {
    case Search     = "SEARCH"
    case Inbox      = "INBOX"
    case Accepted   = "ACCEPTED"
    case Saved      = "SAVED"
    case Declined   = "DECLINED"
    case Organized  = "ORGANIZED"

    static let allValues = [Search, Inbox, Accepted, Saved, Declined, Organized]
    var index : Int {
       return eEventTabType.allValues.indexOf(self)!
    }
}

计数:eEventTabType.allValues.count

index: objeceventtabtype .index

享受:)