给出一个Swift枚举:
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
...
}
(对于项目的需要,我不能够拥有嵌套枚举。)我想只选择带String_
前缀的枚举值。
到目前为止,我所知道的唯一方法是从所有可用案例中做一个随机枚举值,如下:
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))!
}
我怎么能这样做,所以我能够选择一个基于String_
前缀的随机值,而不得不求助于硬编码一个较高的值(例如,new可以添加String_
前缀位置)?感谢
答案 0 :(得分:2)
即使添加了新位置,您也不想更改任何代码。正确?
为此,您需要动态获取所有枚举案例,而不是对其进行硬编码。根据{{3}},您可以使用此方法来获取所有案例:
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
}
}
}
}
获得此cases
方法后,您可以轻松获得所需内容:
let startingWithString = Array(PerformerPosition.cases().filter { "\($0)".hasPrefix("String_") })
let rand = arc4random_uniform(UInt32(startingWithString.count))
let randomPosition = startingWithString[Int(rand)]
答案 1 :(得分:1)
如果您的枚举中有不同的子集,并且您需要单独访问它们,我建议以某种方式识别子集,请考虑:
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
static let strings: [PerformerPosition] = [
.String_Violin1, .String_Violin2, .String_Viola, .String_Cello, .String_CB
]
static let winds: [PerformerPosition] = [
.Wind_Oboe, .Wind_Clarinet, .String_Viola, .Wind_Flute
]
}
请注意,这将为您提供以下几点:
您不需要String_
和Wind_
前缀。您只需使用.violin1
,.oboe
等
您只需从数组中生成随机位置
您可以直接查看您的职位类型:
let isString = PerformerPosition.strings.contains(.violin1)
答案 2 :(得分:0)
我在PlayGround中制作了这个:
func randomPerformer() -> PerformerPosition {
// pick and return a new value
let rand = arc4random_uniform(_count)
let string = String(describing:PerformerPosition(rawValue: rand))
if(string.contains("String_")){
return PerformerPosition(rawValue: rand)!
}else{
return randomPerformer()
}
}