Skip to content

Instantly share code, notes, and snippets.

@dagronf
Created April 30, 2024 00:43
Show Gist options
  • Save dagronf/7ea627f574ea23be101865aa3ba67295 to your computer and use it in GitHub Desktop.
Save dagronf/7ea627f574ea23be101865aa3ba67295 to your computer and use it in GitHub Desktop.
Swift routines for chunking a collection (eg. Data, Array) into an array of chunks
extension Collection {
/// Perform a block on each chunk of `size` elements in this collection
/// - Parameters:
/// - size: The maximum size of the chunk
/// - block: The block to call with the chunk. Set `stop = true` to stop processing
func chunking(into size: Int, _ block: (SubSequence, inout Bool) -> Void) {
var stop = false
var index = 0
while index < self.count {
let offset = index + Swift.min(size, count - index)
let start = self.index(self.startIndex, offsetBy: index)
let end = self.index(self.startIndex, offsetBy: offset)
block(self[start ..< end], &stop)
if stop { return }
index = offset
}
}
/// Perform a block on each chunk of `size` elements in this collection
/// - Parameters:
/// - size: The maximum size of the chunk
/// - block: The block to call with the chunk.
func chunking(into size: Int, _ block: (SubSequence) -> Void) {
let bl: (SubSequence, inout Bool) -> Void = { collection, stop in
block(collection)
}
self.chunking(into: size, bl)
}
/// Chunk the contents of the collection into 'size' based chunks
/// - Parameter size: The size
/// - Returns: An array of subsequence chunks
func chunked(into size: Int) -> [SubSequence] {
var result = [SubSequence]()
result.reserveCapacity((self.count / size) + 1)
self.chunking(into: size) { chunk, stop in result.append(chunk) }
return result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment