How to enumerate an enum with String type?

enumerate, enums, string, swift

Solution

Swift 4.2+

Starting with Swift 4.2 (with Xcode 10), just add protocol conformance to `CaseIterable` to benefit from `allCases`. To add this protocol conformance, you simply need to write somewhere:

extension Suit: CaseIterable {}

If the enum is your own, you may specify the conformance directly in the declaration:

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

Then the following code will print all possible values:

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

Compatibility with earlier Swift versions (3.x and 4.x)

If you need to support Swift 3.x or 4.0, you may mimic the Swift 4.2 implementation by adding the following code:

#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

Problem

``` enum Suit: String { case spades = "♠" case hearts = "♥" case diamonds = "♦" case clubs = "♣" } ``` For example, how can I do something like: ``` for suit in Suit { // do something with suit print(suit.rawValue) } ``` Resulting example: ``` ♠ ♥ ♦ ♣ ```

Original source

Related problems