加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 自定义迭代器,以循环模式无限迭代集合

发布时间:2020-12-14 02:27:04 所属栏目:百科 来源:网络整理
导读:我正在寻找迭代器以循环模式无限迭代集合.因此,当达到收集的结束索引时,迭代器应该在start索引处返回元素. 以下解决方案似乎有效,但我希望它可以更好地制作. public struct LoopIteratorT: Collection: IteratorProtocol { private let collection: T privat
我正在寻找迭代器以循环模式无限迭代集合.因此,当达到收集的结束索引时,迭代器应该在start索引处返回元素.

以下解决方案似乎有效,但我希望它可以更好地制作.

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,3
var 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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读