How to choose a random enumeration value

Swift has gained new features since this answer was written that provide a much better solution — see "How to choose a random enumeration value" instead.


I'm not crazy about your last case there -- it seems like you're including .GeometryClassificationMax solely to enable random selection. You'll need to account for that extra case everywhere you use a switch statement, and it has no semantic value. Instead, a static method on the enum could determine the maximum value and return a random case, and would be much more understandable and maintainable.

enum GeometryClassification: UInt32 {
    case Circle
    case Square
    case Triangle

    private static let _count: GeometryClassification.RawValue = {
        // find the maximum enum value
        var maxValue: UInt32 = 0
        while let _ = GeometryClassification(rawValue: maxValue) { 
            maxValue += 1
        }
        return maxValue
    }()

    static func randomGeometry() -> GeometryClassification {
        // pick and return a new value
        let rand = arc4random_uniform(_count)
        return GeometryClassification(rawValue: rand)!
    }
}

And you can now exhaust the enum in a switch statement:

switch GeometryClassification.randomGeometry() {
case .Circle:
    println("Circle")
case .Square:
    println("Square")
case .Triangle:
    println("Triangle")
}

In Swift there is actually a protocol for enums called CaseIterable that, if you add it to your enum, you can just reference all of the cases as a collection with .allCases as so:

enum GeometryClassification: CaseIterable {

    case Circle
    case Square
    case Triangle

}

and then you can .allCases and then .randomElement() to get a random one

let randomGeometry = GeometryClassification.allCases.randomElement()!

The force unwrapping is required because there is a possibility of an enum having no cases and thus randomElement() would return nil.