【问题标题】:Get element by offset into Sequence通过偏移量获取元素到序列中
【发布时间】:2023-03-13 01:11:01
【问题描述】:

假设我有这个序列:

let fibSequence = sequence(state: (0, 1), next: { (state) -> Int in
    state = (state.1, state.0 + state.1)
    return state.0
})

我可以做一些事情,比如获取前 5 个元素:

print(Array(fibSequence.prefix(5))) // => [1, 1, 2, 3, 5]

但是我怎样才能just 获得索引 5(第 6 个元素)处的元素? (或者如果序列在第 5 个元素之前终止,则返回 nil。)我能想到的最好的方法是:

print(fibSequence.dropFirst(5).makeIterator().next() as Any) // => Optional(8)

是否有内置方法来执行此类操作?

【问题讨论】:

  • 您好,我的回答对您解决这个问题有帮助吗?
  • @DavidRees 啊,感谢您的跟进。之前没注意

标签: swift indexing sequence


【解决方案1】:

我认为您的想法是正确的,目前还没有一种方法可以对序列进行索引,但是使用 Sequence 上的扩展很容易实现:

extension Sequence {
    subscript(index: Int) -> Self.Iterator.Element? {
        return enumerated().first(where: {$0.offset == index})?.element
    }
}

这意味着您可以像这样轻松索引序列:

print(fibSequence[8])

另外,我发现您可以使用此逻辑来索引一个特定元素,从而消除对任何警告的强制转换

let fibSequence = sequence(state: (0, 1), next: { (state) -> Int in
    state = (state.1, state.0 + state.1)
    return state.0
})
print(fibSequence.enumerated().first(where: {$0.offset == 5})?.element)

【讨论】:

  • 我建议不要在此处添加下标;下标看起来像 O(1) 运算——for i in 5 ..< n { print(fibSequence[i]) } 看起来是线性的,但会意外地是二次的。对于破坏性序列,它也会有相当混乱的语义;例如考虑class Counter : Sequence, IteratorProtocol { var i = 0; func next() -> Int? { defer { i += 1 }; return i }}let c = Counter(); print(c[5] == c[5]) 返回 false,这可能令人惊讶,因为下标看起来不像是破坏性操作。
  • 是的,我完全同意,您已经完美地证明了为什么 Sequence 类上没有下标方法。
猜你喜欢
  • 2016-02-25
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多