我试图将下面的Swift 2扩展方法转换为Swift 3。
extension CollectionType {
func chunk(withDistance distance: Index.Distance) -> [[SubSequence.Generator.Element]] {
var index = startIndex
let generator: AnyGenerator<Array<SubSequence.Generator.Element>> = anyGenerator {
defer { index = index.advancedBy(distance, limit: self.endIndex) }
return index != self.endIndex ? Array(self[index ..< index.advancedBy(distance, limit: self.endIndex)]) : nil
}
return Array(generator)
}
}
Xcode转换工具给我留下了这个。
extension Collection {
func chunk(withDistance distance: Int) -> [[SubSequence.Iterator.Element]] {
var index = startIndex
let generator: AnyGenerator<Array<SubSequence.Generator.Element>> = anyGenerator {
defer { index = index.advancedBy(distance, limit: self.endIndex) }
return index != self.endIndex ? Array(self[index ..< index.advancedBy(distance, limit: self.endIndex)]) : nil
}
return Array(generator)
}
}
现在我在行let generator: AnyGenerator<Array<SubSequence.Generator.Element>> = anyGenerator {
处收到了上述错误。我无法弄清楚如何解决这个问题。
答案 0 :(得分:2)
有几个问题:
Generator
已在Swift 3中重命名为Iterator
,因此
AnyGenerator
至AnyIterator
。IndexDistance
是Collection
的关联类型
表示索引之间的步数。总而言之,您的方法可以像这样在Swift 3中查找:
extension Collection {
func chunk(withDistance distance: IndexDistance) -> [[SubSequence.Iterator.Element]] {
var pos = startIndex
let iterator: AnyIterator<Array<SubSequence.Iterator.Element>> = AnyIterator {
// Already at the end?
if pos == self.endIndex { return nil }
// Compute `pos + distance`, but not beyond `self.endIndex`:
let endPos = self.index(pos, offsetBy: distance, limitedBy: self.endIndex) ?? self.endIndex
// Return chunk and advance `pos`:
defer { pos = endPos }
return Array(self[pos..<endPos])
}
return Array(iterator)
}
}
let a = [1, 2, 3, 4, 5, 6, 7]
let c = a.chunk(withDistance: 2)
print(c) // [[1, 2], [3, 4], [5, 6], [7]]
我已将本地index
变量重命名为pos
,以避免
与
public func index(_ i: Self.Index, offsetBy n: Self.IndexDistance, limitedBy limit: Self.Index) -> Self.Index?
用于推进索引的Collection
方法。
当然,您可以使用while
循环获得相同的结果
而不是Iterator
:
extension Collection {
func chunk(withDistance distance: IndexDistance) -> [[SubSequence.Iterator.Element]] {
var result: [[SubSequence.Iterator.Element]] = []
var pos = startIndex
while pos != endIndex {
let endPos = self.index(pos, offsetBy: distance, limitedBy: self.endIndex) ?? self.endIndex
result.append(Array(self[pos..<endPos]))
pos = endPos
}
return result
}
}