Swift 将选项SetType映射到数组
鉴于以下情况:Swift 将选项SetType映射到数组,swift,Swift,鉴于以下情况: struct Weekdays: OptionSetType { let rawValue: Int init(rawValue: Int) { self.rawValue = rawValue } static let Monday = Weekdays(rawValue: 1) static let Tuesday = Weekdays(rawValue: 2) static let Wednesday = Weekdays(raw
struct Weekdays: OptionSetType {
let rawValue: Int
init(rawValue: Int) { self.rawValue = rawValue }
static let Monday = Weekdays(rawValue: 1)
static let Tuesday = Weekdays(rawValue: 2)
static let Wednesday = Weekdays(rawValue: 4)
static let Thursday = Weekdays(rawValue: 8)
static let allOptions: [Weekdays] = [.Monday, .Tuesday, .Wednesday, .Thursday]
}
通过执行以下操作,我可以将整数数组
转换为工作日
对象:
let arr = [1, 4]
let weekdays = arr.reduce(Weekdays()) { $0.union(Weekdays(rawValue: $1)) }
我的问题是,我如何将一个
平日
对象转换成一个整数数组
?当我写这个问题时,我发现:
let array = Weekdays.allOptions.filter { weekdays.contains($0) }.map { $0.rawValue }
有更好的方法吗?(不一定更好,但用不同的方法来看待它,并稍微
(更一般)
OptionSetType
继承自RawRepresentable
,因此可以
从关联的原始类型转换为关联的原始类型,在您的示例中是
Int
因此,“缺失链接”是原始值之间的转换(例如5
)
以及位分量的整数数组(例如[1,4]
)
这可以通过Int
扩展方法完成:
extension Int {
init(bitComponents : [Int]) {
self = bitComponents.reduce(0, combine: (+))
}
func bitComponents() -> [Int] {
return (0 ..< 8*sizeof(Int)).map( { 1 << $0 }).filter( { self & $0 != 0 } )
}
}
和反向转换
let array = weekdays.rawValue.bitComponents()
print(array)
// [1, 4]
优点:
- 不需要明确定义
allOptions:
- 它可以应用于其他选项集类型(具有
作为原始值)Int
IntegerType
,因此同样适用于其他整数原始类型。然而,这似乎有点复杂/丑陋
因为左移位运算符
不能准确回答问题,但可能对其他人有用。根据Martin的回答,我提取了组件对象:
extension FixedWidthInteger {
init(bitComponents : [Self]) {
self = bitComponents.reduce(0, +)
}
var bitComponents : [Self] {
(0 ..< Self.bitWidth).map { 1 << $0 } .filter { self & $0 != 0 }
}
}
extension OptionSet where RawValue: FixedWidthInteger, Self == Self.Element {
var components : [Self] { rawValue.bitComponents.map(Self.init) }
}
扩展名FixedWidthInteger{
初始化(位组件:[Self]){
self=bitComponents.reduce(0,+)
}
变量bitComponents:[自身]{
(0..OptionSet
上定义扩展来改进扩展的上下文
扩展选项起始,其中RawValue:UnsignedInteger{
var individualCases:[自身]{
返回(0..我喜欢这样一个事实,即不再需要Alloption。不过,我的解决方案比这个解决方案有一个优势…我的解决方案可以创建任何类型的数组,而不仅仅是rawValue类型。在我的实际用例中,我将从选项集类型
映射到字符串
的数组。也就是说,您的答案涵盖了具体的用例这个问题我回答得很好!谢谢。
extension Int {
init(bitComponents : [Int]) {
self = bitComponents.reduce(0, +)
}
func bitComponents() -> [Int] {
return (0 ..< 8*MemoryLayout<Int>.size).map( { 1 << $0 }).filter( { self & $0 != 0 } )
}
}
extension FixedWidthInteger {
init(bitComponents : [Self]) {
self = bitComponents.reduce(0, +)
}
var bitComponents : [Self] {
(0 ..< Self.bitWidth).map { 1 << $0 } .filter { self & $0 != 0 }
}
}
extension OptionSet where RawValue: FixedWidthInteger, Self == Self.Element {
var components : [Self] { rawValue.bitComponents.map(Self.init) }
}