Given a Swift enum as such:
enum PerformerPosition: Int {
case String_Violin1
case String_Violin2
case String_Viola
case String_Cello
case String_CB
case Wind_Oboe
case Wind_Clarinet
case Wind_Flute
...
}
(For the needs of the project, I am not able to have a nested enum.) I would like to randomly select an enum value with the String_
prefix, only.
The only way I know so far is to do a random enum value from all the available cases, as such:
private static let _count: PerformerPosition.RawValue = {
// find the maximum enum value
var maxValue: Int = 0
while let _ = PerformerPosition(rawValue: maxValue) {
maxValue += 1
}
return maxValue
}()
static func randomPerformer() -> PerformerPosition {
// pick and return a new value
let rand = arc4random_uniform(UInt32(count))
return PlayerPosition(rawValue: Int(rand))!
}
How could I make it so I am able to pick a random value based on the String_
prefix only without having to resort to hard-coding an upper value (for example, new String_
prefix positions may be added)? Thanks
So you don't want to change any of the code even if a new position is added. Right?
To do that, you need to get all the enum cases dynamically, instead of hardcoding them. According to this answer, you can use this method to get all the cases:
protocol EnumCollection : Hashable {}
extension EnumCollection {
static func cases() -> AnySequence<Self> {
typealias S = Self
return AnySequence { () -> AnyIterator<S> in
var raw = 0
return AnyIterator {
let current : Self = withUnsafePointer(to: &raw) { $0.withMemoryRebound(to: S.self, capacity: 1) { $0.pointee } }
guard current.hashValue == raw else { return nil }
raw += 1
return current
}
}
}
}
After you got this cases
method, you can easily get what you want by:
let startingWithString = Array(PerformerPosition.cases().filter { "\($0)".hasPrefix("String_") })
let rand = arc4random_uniform(UInt32(startingWithString.count))
let randomPosition = startingWithString[Int(rand)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With