微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

swift – 从枚举的子部分中选择一个随机值

给出一个 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_前缀的随机值,而不必求助于硬编码一个较高的值(例如,可以添加新的String_前缀位置)?谢谢

解决方法

因此,即使添加了新位置,您也不想更改任何代码.对?

要做到这一点,您需要动态获取所有枚举案例,而不是硬编码它们.根据this answer,您可以使用此方法获取所有情况:

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
            }
        }
    }
}

获得此案例方法后,您可以轻松获得所需内容

let startingWithString = Array(PerformerPosition.cases().filter { "\($0)".hasPrefix("String_") })
let rand = arc4random_uniform(UInt32(startingWithString.count))
let randomPosition = startingWithString[Int(rand)]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐