鉴于以下内容:
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]
}
Run Code Online (Sandbox Code Playgroud)
我可以通过这样做将数组Ints转换为Weekdays对象:
let arr = [1, 4]
let weekdays = arr.reduce(Weekdays()) { $0.union(Weekdays(rawValue: $1)) }
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何获取一个Weekdays对象并将其转换为一个数组Ints?
(不一定更好,但以不同的方式来看待它并稍微更一般).
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 } )
}
}
Run Code Online (Sandbox Code Playgroud)
然后你从数组到Weekdays对象的转换成为
let arr : [Int] = [1, 4]
let weekdays = Weekdays(rawValue: Int(bitComponents: arr))
print(weekdays)
// app.Weekdays(rawValue: 5)
Run Code Online (Sandbox Code Playgroud)
和反向转换
let array = weekdays.rawValue.bitComponents()
print(array)
// [1, 4]
Run Code Online (Sandbox Code Playgroud)
好处:
allOptions:不需要明确的定义.Int
原始值).也可以尝试将转换定义为协议扩展,例如IntegerType,也可以将其与其他整数原始类型一起使用.然而,这似乎有点复杂/丑陋,因为左移操作符<<不是
IntegerType(或任何)协议的一部分.
Swift 3更新:
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 } )
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1183 次 |
| 最近记录: |