LoginSignup
24
22

More than 5 years have passed since last update.

Swiftでenumの要素数(項目数)を得られるようにするには

Last updated at Posted at 2014-12-16

はじめに

自動的に0から連番を振ってもらえる整数の列挙型に限定した内容です。

  • Xcode 6.1.1 + Playground

CやObjCでは以下のような感じで最後に適当な要素を用意してカウントするのが定石だと思いますが、

Objective-C
// 名前はいい加減です。
typedef enum {
    A = 0
    B,
    C,

    count, // カウンタ
} Test;

Swiftの列挙型で同様の事を実現する方法を考えてみました。

案1

以下のような方法が簡単でしょうか。

Swift
import UIKit

enum Test: Int {
    case A
    case B
    case C

    case _count // ダミーカウンタ
    static let count = _count.rawValue // 利用するものはこちら
}

println(Test.count) // 3

これなら利用時にわざわざrawValueやコンバージョンを利用しなくてもInt型として要素数が利用できるかなと。

特に、次のような、要素の型がInt型以外の場合に効果が有るのではないかと思います。

Swift
import UIKit

enum Test: UInt8 {
    case A
    case B
    case C

    case _count // ダミーカウンタ
    static let count = Int(_count.rawValue) // Int型へコンバージョン
}

// こういった引数にInt型を要求されるような場所で可読性が上がる気がします。
let array = [Hoge](count: Test.count, repeatedValue: Hoge())

案2

tottokotkd様よりコメントを頂きまして、それをヒントに自分なりにいじってみました。

import UIKit

/// 列挙体の要素数をカウントします。
func countEnumElements(test: (Int) -> Any?) -> Int {
    var i = 0
    while test(i) != nil {
        i++
    }
    return i
}

enum TestInt: Int {
    case A
    case B
    case C
    case D

    static let count = countEnumElements({TestInt(rawValue: $0)})
}

enum TestUInt8: UInt8 {
    case A
    case B
    case C

    static let count = countEnumElements({TestUInt8(rawValue: UInt8($0))})
}

println(TestInt.count) // 4
println(TestUInt8.count) // 3

こちらの方はダミーカウンタ(_count)が不要なので、少しスッキリするかもしれません。
ただ、初回実行時にカウント処理が1回は走りますので、膨大な要素数が存在する場合は案1の方が高速かと予想されます。

終わりに

もっと良い方法があれば教えて下さい。

24
22
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
22