Hello Swift Community :))
Based on the slice collection API the Swift Std have today we mostly can slice a collection by a separator or a closure that takes each value and decides if it gonna slice in that position.
The pitch here is to provide a method on the collections that allows us to slice a collection in slices of a given size.
Example:
Given the array: ["1", "2", "3","4", "5", "6","7", "8", "9", "10"]
Calling array.split(size: 3) will produce the output:
[ArraySlice(["1", "2", "3"]), ArraySlice(["4", "5", "6"]), ArraySlice(["7", "8", "9"]), ArraySlice(["10"])]
Proposed Implementation
extension RandomAccessCollection {
func split(size: Int) -> [SubSequence] {
precondition(size > 0, "Split size should be greater than 0.")
var idx = startIndex
var splits = [SubSequence]()
splits.reserveCapacity(count/size)
while idx < endIndex {
let advanced = Swift.min(index(idx, offsetBy: size), endIndex)
splits.append(self[idx..<advanced])
idx = advanced
}
return splits
}
}
let array = (1...10).map({ "\($0)" })
print("Result: \(array.split(size: 3))")
print("Result Even: \(array.split(size: 5))")
// Result: [ArraySlice(["1", "2", "3"]), ArraySlice(["4", "5", "6"]), ArraySlice(["7", "8", "9"]), ArraySlice(["10"])]
// Result Even: [ArraySlice(["1", "2", "3", "4", "5"]), ArraySlice(["6", "7", "8", "9", "10"])]
This is a common API in some other libs in other languages like
Some points to consider here:
- I'm not 100% sure if
split(size:)
is actually the best naming here. Another option I thought will besplit(ofSize: )
. - A
forEachSlice(size: Int, _ body: (SubSequence) throws -> Void) rethrows
like the ruby each_slice is not the topic of this pitch, but it's something to mention here for maybe a futher discussion.
That's it for the pitch, looking forward to hear the thoughts from the community