[swift] Swift 열거 형의 수는 어떻게 얻습니까?

Swift 열거 형에서 사례 수를 어떻게 확인할 수 있습니까?

( 모든 값을 수동으로 열거 하거나 가능한 경우 이전 ” enum_count trick “을 사용하지 않기를 원합니다 .)



답변

Swift 4.2 (Xcode 10)부터 CaseIterable프로토콜 준수를 선언 할 수 있으며 관련 값이없는 모든 열거에 작동합니다.

enum Stuff: CaseIterable {
    case first
    case second
    case third
    case forth
}

사례 수는 이제 간단히

print(Stuff.allCases.count) // 4

자세한 내용은


답변

이에 대한 자세한 내용 의 블로그 게시물 이 있지만 열거 형의 원시 유형이 정수이면 다음과 같이 카운트를 추가 할 수 있습니다.

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


답변

Xcode 10 업데이트

CaseIterable열거 형 의 프로토콜을 채택하면 allCases모든 열거 형 케이스를 포함 하는 정적 속성을 제공 합니다 Collection. 그냥 사용count 속성을 하여 열거 형의 사례 수를 알 수 있습니다.

예를 들어 Martin의 답변을 참조하십시오 (그리고 내 대답보다는 찬성 투표하십시오)


경고 : 아래 방법은 더 이상 작동하지 않는 것 같습니다.

열거 형 수를 계산하는 일반적인 방법을 알지 못합니다. 그러나 hashValue열거 형 사례 의 속성은 0부터 시작하여 사례가 선언 된 순서에 따라 결정되는 점진적 인 것으로 나타났습니다 . 따라서 마지막 열거 형의 해시에 1을 더한 경우는 사례 수에 해당합니다.

예를 들어이 열거 형을 사용하면 :

enum Test {
    case ONE
    case TWO
    case THREE
    case FOUR

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

count 4를 반환합니다.

나는 그것이 규칙인지 또는 미래에 변경 될 것인지 말할 수 없으므로 자신의 책임하에 사용하십시오 🙂


답변

Nate Cook이 게시 한 접근 방식에 따라 사례 수를 자동으로 수행하는 재사용 가능한 프로토콜을 정의합니다.

protocol CaseCountable {
    static var caseCount: Int { get }
}

extension CaseCountable where Self: RawRepresentable, Self.RawValue == Int {
    internal static var caseCount: Int {
        var count = 0
        while let _ = Self(rawValue: count) {
            count += 1
        }
        return count
    }
}

그런 다음이 프로토콜을 예를 들어 다음과 같이 재사용 할 수 있습니다.

enum Planet : Int, CaseCountable {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
//..
print(Planet.caseCount)


답변

답변에 표시된 것처럼 정적 allValues ​​배열을 만듭니다.

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

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

...

let count = ProductCategory.allValues.count

이것은 값을 열거하고 모든 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!")
  }
}


답변

이러한 종류의 함수는 열거의 개수를 반환 할 수 있습니다.

스위프트 2 :

func enumCount<T: Hashable>(_: T.Type) -> Int {
    var i = 1
    while (withUnsafePointer(&i) { UnsafePointer<T>($0).memory }).hashValue != 0 {
        i += 1
    }
    return i
}

스위프트 3 :

func enumCount<T: Hashable>(_: T.Type) -> Int {
   var i = 1
   while (withUnsafePointer(to: &i, {
      return $0.withMemoryRebound(to: T.self, capacity: 1, { return $0.pointee })
   }).hashValue != 0) {
      i += 1
   }
      return i
   }