如何在不使用位置(索引)i
和for
/ for in
循环的情况下迭代数组?
var a = [1, 2, 3]
for var i = 0; i < a.count; i++ {
//
}
for item in a {
//
}
答案 0 :(得分:1)
SequenceType
(CollectionType
,因此所有包含数组的Swift集合都符合)非常简单。它要求您提供generate()
函数,该函数返回符合GeneratorType
的类型。
GeneratorType
反过来只需要提供一个方法:一个next()
返回每个元素,直到元素用完为止。它返回一个可选项,在返回最后一个元素后返回nil
。这使得它们非常类似于Java迭代器,只有next
和hasNext
通过使用选项合并为一个。
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
的更多信息