Skip to content

Commit

Permalink
Add chunks(ofSize:) function to Collection extension
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeehut committed Dec 7, 2024
1 parent eef1821 commit bdeb125
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
53 changes: 53 additions & 0 deletions Sources/HandySwift/Extensions/CollectionExt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,59 @@ extension Collection {
public subscript(safe index: Index) -> Element? {
self.indices.contains(index) ? self[index] : nil
}

/// Splits the collection into smaller chunks of the specified size.
///
/// This method is useful for processing large datasets in manageable pieces, such as logging data, sending network requests, or performing batch updates.
///
/// - Parameter size: The size of each chunk. Must be greater than 0.
/// - Returns: An array of arrays, where each subarray represents a chunk of elements. The last chunk may contain fewer elements if the collection cannot be evenly divided.
///
/// - Example:
/// ```swift
/// let numbers = Array(1...10)
/// let chunks = numbers.chunks(ofSize: 3)
/// print(chunks)
/// // Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
/// ```
///
/// - Example: Processing items in chunks
/// ```swift
/// let tasks = ["Task1", "Task2", "Task3", "Task4"]
/// for chunk in tasks.chunks(ofSize: 2) {
/// for task in chunk {
/// task.perform()
/// }
///
/// print("Processed chunk of tasks: \(chunk)")
/// }
/// // Output:
/// // Processed chunk of tasks: ["Task1", "Task2"]
/// // Processed chunk of tasks: ["Task3", "Task4"]
/// ```
public func chunks(ofSize size: Int) -> [[Element]] {
guard size > 0 else { fatalError("Chunk size must be greater than 0.") }

var result: [[Element]] = []
var chunk: [Element] = []
var count = 0

for element in self {
chunk.append(element)
count += 1
if count == size {
result.append(chunk)
chunk.removeAll(keepingCapacity: true)
count = 0
}
}

if !chunk.isEmpty {
result.append(chunk)
}

return result
}
}

extension Collection where Element: DivisibleArithmetic {
Expand Down
13 changes: 9 additions & 4 deletions Tests/HandySwiftTests/Extensions/CollectionExtTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@ class CollectionExtTests: XCTestCase {
let intArray = [1, 2, 10]
XCTAssertEqual(intArray.average(), 4.333, accuracy: 0.001)

#if canImport(CoreGraphics)
#if canImport(CoreGraphics)
let averageAsCGFloat: CGFloat = intArray.average()
XCTAssertEqual(averageAsCGFloat, 4.333, accuracy: 0.001)
#endif
#endif

let doubleArray = [1.0, 2.0, 10.0]
XCTAssertEqual(doubleArray.average(), 4.333, accuracy: 0.001)

#if canImport(CoreGraphics)
#if canImport(CoreGraphics)
let cgFloatArray: [CGFloat] = [1.0, 2.0, 10.0]
XCTAssertEqual(cgFloatArray.average(), 4.333, accuracy: 0.001)
#endif
#endif
}

func testChunks() {
XCTAssertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].chunks(ofSize: 3), [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]])
XCTAssertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].chunks(ofSize: 5), [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
}
}

0 comments on commit bdeb125

Please sign in to comment.