1. ホーム
  2. swift

[解決済み] String型のenumを列挙する方法は?

2022-03-18 13:58:25

質問

enum Suit: String {
    case spades = "♠"
    case hearts = "♥"
    case diamonds = "♦"
    case clubs = "♣"
}

例えば、どうすればこんなことができるのでしょう。

for suit in Suit {
    // do something with suit
    print(suit.rawValue)
}

結果の例

♠
♥
♦
♣

解決方法は?

Swift 4.2+

で始まる Swift 4.2 (Xcode 10で) プロトコル適合性を CaseIterable の恩恵を受けることができます。 allCases . このプロトコル適合性を追加するには、単にどこかに書くだけでよい。

extension Suit: CaseIterable {}

enumが独自のものである場合、宣言の中で直接適合性を指定することができます。

enum Suit: String, CaseIterable { case spades = "♠"; case hearts = "♥"; case diamonds = "♦"; case clubs = "♣" }

次に、以下のコードで、可能なすべての値を表示します。

Suit.allCases.forEach {
    print($0.rawValue)
}


以前のSwiftバージョン(3.xおよび4.x)との互換性

Swift 3.x または 4.0 に対応する必要がある場合、以下のコードを追加することで Swift 4.2 の実装を模倣することができます。

#if !swift(>=4.2)
public protocol CaseIterable {
    associatedtype AllCases: Collection where AllCases.Element == Self
    static var allCases: AllCases { get }
}
extension CaseIterable where Self: Hashable {
    static var allCases: [Self] {
        return [Self](AnySequence { () -> AnyIterator<Self> in
            var raw = 0
            var first: Self?
            return AnyIterator {
                let current = withUnsafeBytes(of: &raw) { $0.load(as: Self.self) }
                if raw == 0 {
                    first = current
                } else if current == first {
                    return nil
                }
                raw += 1
                return current
            }
        })
    }
}
#endif