Thanks for the suggestion! I’ve tried a few permutations of this. First, if we drop the Index == Int requirement:
extension Collection {
public func chunked(into size: Index.Stride) -> [SubSequence] {
precondition(
size > 0,
"Calls to `chunked(into:)` must have a `size` greater than 0")
return stride(from: startIndex, to: endIndex, by: size).map { index in
let endIndex = self.index(index,
offsetBy: size,
limitedBy: self.endIndex) ?? self.endIndex
return self[index ..< endIndex]
}
}
}
This fails with this error:
CollectionChunks.swift:38:16: error: cannot invoke 'stride' with an argument list of type '(from: Self.Index, to: Self.Index, by: Int)'
return stride(from: startIndex, to: endIndex, by: size).map { index in
^
Next, let’s try constraining it to Collections where the Index conforms to Strideable:
extension Collection where Index: Strideable {
public func chunked(into size: Index.Stride) -> [SubSequence] {
precondition(
size > 0,
"Calls to `chunked(into:)` must have a `size` greater than 0")
return stride(from: startIndex, to: endIndex, by: size).map { index in
let endIndex = self.index(index,
offsetBy: size,
limitedBy: self.endIndex) ?? self.endIndex
return self[index ..< endIndex]
}
}
}
This fails with this error:
CollectionChunks.swift:40:49: error: argument type 'Self.Index.Stride' does not conform to expected type 'BinaryInteger'
offsetBy: size,
^
OK, so we make sure that the Stride of the Index conforms to BinaryInteger:
extension Collection where Index: Strideable, Index.Stride: BinaryInteger {
public func chunked(into size: Index.Stride) -> [SubSequence] {
precondition(
size > 0,
"Calls to `chunked(into:)` must have a `size` greater than 0")
return stride(from: startIndex, to: endIndex, by: size).map { index in
let endIndex = self.index(index,
offsetBy: size,
limitedBy: self.endIndex) ?? self.endIndex
return self[index ..< endIndex]
}
}
}
Now we appear to hit a deprecation error:
CollectionChunks.swift:39:33: error: 'index(_:offsetBy:limitedBy:)' is unavailable: all index distances are now of type Int
let endIndex = self.index(index,
^~~~~
Swift.Collection:11:17: note: 'index(_:offsetBy:limitedBy:)' was obsoleted in Swift 5.0
public func index<T>(_ i: Self.Index, offsetBy n: T, limitedBy limit: Self.Index) -> Self.Index? where T : BinaryInteger
^
The only combination I’ve had that’s worked is constraining Index to Int, but then I can’t use it on String. I’m happy to continue trying permutations of generic constraints if we can find something that works in all cases!