Quick version that follows more of a collection consumer approach. This also has an example that illustrates the issue with the Int
constrained version.
extension Collection {
public func chunked_orignal(into size: Int) -> [SubSequence] {
var chunks: [SubSequence] = []
var i = startIndex
while let nextIndex = index(i, offsetBy: size, limitedBy: endIndex) {
let chunk = self[i ..< nextIndex]
chunks.append(chunk)
i = nextIndex
}
if i != endIndex {
chunks.append(self[i...])
}
return chunks
}
}
print("Original")
print([1,2,3,4,5,6,7,8,9,10].chunked_orignal(into: 2))
print([1,2,3,4,5,6,7,8,9,10].lazy.filter { $0 % 2 == 0 }.chunked_orignal(into: 2).map { Array($0) })
extension Collection where Index == Int {
public func chunked_broken(into size: Index.Stride) -> [SubSequence] {
return stride(from: startIndex, to: endIndex, by: size).map { index in
let end = self.index(index, offsetBy: size, limitedBy: self.endIndex) ?? endIndex
return self[index ..< end]
}
}
}
print("Broken")
print([1,2,3,4,5,6,7,8,9,10].chunked_broken(into: 2))
print([1,2,3,4,5,6,7,8,9,10].lazy.filter { $0 % 2 == 0 }.chunked_broken(into: 2).map { Array($0) })
extension Collection {
public func chunked_consumer(into size: Int) -> [SubSequence] {
var chunks: [SubSequence] = []
var rest = self[...]
while !rest.isEmpty {
chunks.append(rest.prefix(size))
rest = rest.dropFirst(size)
}
return chunks
}
}
print("Consuming")
print([1,2,3,4,5,6,7,8,9,10].chunked_consumer(into: 2))
print([1,2,3,4,5,6,7,8,9,10].lazy.filter { $0 % 2 == 0 }.chunked_consumer(into: 2).map { Array($0) })
The prefix/dropFirst
combo is the sort of thing discussed here under "Collection Consumers".