以下解决方案似乎有效,但我希望它可以更好地制作.
public struct LoopIterator<T: Collection>: IteratorProtocol { private let collection: T private var startIndexOffset: T.Indexdistance public init(collection: T) { self.collection = collection startIndexOffset = 0 } public mutating func next() -> T.Iterator.Element? { guard !collection.isEmpty else { return nil } let index = collection.index(collection.startIndex,offsetBy: startIndexOffset) startIndexOffset += T.Indexdistance(1) if startIndexOffset >= collection.count { startIndexOffset = 0 } return collection[index] }}extension Array { func makeLoopIterator() -> LoopIterator<Array> { return LoopIterator(collection: self) }}// Testing...// Will print: 1,2,3,1,3var it = [1,3].makeLoopIterator()for _ in 0..<6 { print(it.next())}
这是做自定义迭代器的正确方法吗?有什么可以改进的?
谢谢!
在Swift 3(您正在使用)中,索引旨在由集合本身进行处理.有了它,您可以按如下方式简化:public struct LoopIterator<Base: Collection>: IteratorProtocol { private let collection: Base private var index: Base.Index public init(collection: Base) { self.collection = collection self.index = collection.startIndex } public mutating func next() -> Base.Iterator.Element? { guard !collection.isEmpty else { return nil } let result = collection[index] collection.formIndex(after: &index) // (*) See discussion below if index == collection.endindex { index = collection.startIndex } return result }}
现在我们只需向前移动索引,如果它现在指向结尾,则将其重置为开头.无需计数或Indexdistance.
请注意,我在这里使用了formIndex,因为你的Iterator可以处理任何Collection(因此也适用于任何索引),因此可以在某些模糊的情况下(特别是在AnyIndex周围)提高性能.更简单的版本是index = collection.index(after:index),在大多数情况下可能更好.
有关Swift 3指数的所有详细信息,请参阅SE-0065.
总结以上是内存溢出为你收集整理的swift – 自定义迭代器,以循环模式无限迭代集合全部内容,希望文章能够帮你解决swift – 自定义迭代器,以循环模式无限迭代集合所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)