首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >CaseItearble的泛型next()和previous()方法

CaseItearble的泛型next()和previous()方法
EN

Stack Overflow用户
提问于 2019-03-21 02:14:57
回答 1查看 97关注 0票数 1

假设我们有一个枚举,并希望枚举它:)。如果它有Int rawValue,我们可以使用像这样的计算变量为我们提供下一个和前一个项目。

代码语言:javascript
复制
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()。

代码语言:javascript
复制
// 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: )

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-21 03:38:24

您可以通过以下方式使用offsetBy实现previous()

代码语言:javascript
复制
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()

代码语言:javascript
复制
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
        }
    }
}

并像这样使用它

代码语言:javascript
复制
let average = Fidelity.average  //average
average.advanced(by: 1)         //datapoint
average.advanced(by: 2)         //nil
average.advanced(by: -3)        //pixel
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55267612

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档