假设我们有一个枚举,并希望枚举它:)。如果它有Int rawValue,我们可以使用像这样的计算变量为我们提供下一个和前一个项目。
enum Fidelity: Int, CaseIterable {
case pixel
case point
case average
case datapoint
var previousFidelity: Fidelity {
return Fidelity(rawValue: rawValue - 1) ?? .pixel
}
var nextFidelity: Fidelity {
return Fidelity(rawValue: rawValue + 1) ?? .datapoint
}
}
我更进一步,为CaseIterable创建了一个扩展,它允许对多种类型使用next()和previous()。
// Let's test Swift 4.2 for enumerating enum
// Too complex, not very efficient, but interesting
extension CaseIterable where Self: Equatable {
func next() -> Self? {
let all = Self.allCases
let idx = all.index(of: self)!
let next = all.index(after: idx)
return (next == all.endIndex) ? nil : all[next]
}
func previous() -> Self? {
let all_reversed = Self.allCases.reversed()
let idx = all_reversed.index(of: self)!
let next = all_reversed.index(after: idx)
return (next == all_reversed.endIndex) ? nil : all_reversed[next]
}
}
问题是我的解决方案的效率如何(即速度、内存)?有没有什么想法可以做同样或相似的事情,比如offset(by: )
。
发布于 2019-03-21 03:38:24
您可以通过以下方式使用offsetBy
实现previous()
:
func previous() -> Self? {
let all = Self.allCases
var idx = all.index(of: self)!
if idx == all.startIndex {
return nil
} else {
all.formIndex(&idx, offsetBy: -1)
return all[idx]
}
}
您可以在更通用的偏移量函数中同时使用next()
和previous()
:
extension CaseIterable where Self: Equatable {
func advanced(by n: Int) -> Self? {
let all = Self.allCases
let idx = all.index(of: self)!
//An enum with a raw type has at least one case
let lastIndex = all.index(all.endIndex, offsetBy: -1)
let limit = n > 0 ? lastIndex : all.startIndex
if let newIndex = all.index(idx, offsetBy: n, limitedBy: limit) {
return all[newIndex]
} else {
return nil
}
}
}
并像这样使用它
let average = Fidelity.average //average
average.advanced(by: 1) //datapoint
average.advanced(by: 2) //nil
average.advanced(by: -3) //pixel
https://stackoverflow.com/questions/55267612
复制相似问题