Swift中类似Java的迭代器

时间:2015-07-07 14:43:56

标签: swift iterator

如何在不使用位置(索引)ifor / for in循环的情况下迭代数组?

var a = [1, 2, 3]

for var i = 0; i < a.count; i++ {
    //
}

for item in a {
    //
}

4 个答案:

答案 0 :(得分:1)

SequenceTypeCollectionType,因此所有包含数组的Swift集合都符合)非常简单。它要求您提供generate()函数,该函数返回符合GeneratorType的类型。

GeneratorType反过来只需要提供一个方法:一个next()返回每个元素,直到元素用完为止。它返回一个可选项,在返回最后一个元素后返回nil。这使得它们非常类似于Java迭代器,只有nexthasNext通过使用选项合并为一个。

Swift的for…in对于获取生成器然后在其上反复调用next的组合来说实际上是语法糖:

let a = [1, 2, 3]
for i in a { print(i) }
// is equivalent to:
var g = a.generate()
// the generator, being stateful, must be declared with var
while let i = g.next() { print(i) }

如果使用这样的生成器,请注意std lib doc中GeneratorType定义上方的注释:

  

封装迭代状态和接口以进行迭代   序列

     
      
  • 注意:虽然可以安全地复制生成器,然后推进生成器   复制可能使其他人无效。
  •   

由于为集合编写生成器通常涉及大量锅炉板,因此可以使用辅助类型IndexingGenerator。这实现了一个从startIndex开始的生成器,并返回该索引处的值并每次递增索引。返回generate()的{​​{1}}作为IndexingGenerator的默认实现提供,这意味着如果这对您的目的而言足够好,则无需实现CollectionType实施集合时:

generate

此默认值已在Swift 2.0中添加。在此之前,您必须提供一个只返回struct Bitfield: CollectionType { let data: UInt var startIndex: UInt { return 0 } var endIndex: UInt { return UInt(sizeofValue(data)*8) } subscript(idx: UInt) -> Bit { return (data >> idx) & 1 == 0 ? Bit.Zero : Bit.One } // no need to implement generate() } 的最小生成器。

答案 1 :(得分:0)

您可以使用IndexingGenerator执行此操作:

var a = [1, 2, 3]

var generator = a.generate()

while let item = generator.next() {
    //
}

<强> P上。 S。我创建并回答了我自己的问题,因为在试图弄清楚如何在Swift中使用类似Java的迭代器时我没有找到任何东西。

答案 2 :(得分:0)

如果您使用Java 8,则可以使用流。 举个例子:

List<User> olderUsers = users.stream().filter(u -> u.age > 30).collect(Collectors.toList());

答案 3 :(得分:0)

可以在IteratorProtocol的帮助下完成。

let a = [1, 2, 3]
var aIterator = a.makeIterator()

while let aItem = aIterator.next() {
    // do something with array item
}

Apple文档here中的IteratorProtocol的更多信息