Skip to content

Commit bdeb125

Browse files
committed
Add chunks(ofSize:) function to Collection extension
1 parent eef1821 commit bdeb125

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

Sources/HandySwift/Extensions/CollectionExt.swift

+53
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,59 @@ extension Collection {
1818
public subscript(safe index: Index) -> Element? {
1919
self.indices.contains(index) ? self[index] : nil
2020
}
21+
22+
/// Splits the collection into smaller chunks of the specified size.
23+
///
24+
/// This method is useful for processing large datasets in manageable pieces, such as logging data, sending network requests, or performing batch updates.
25+
///
26+
/// - Parameter size: The size of each chunk. Must be greater than 0.
27+
/// - 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.
28+
///
29+
/// - Example:
30+
/// ```swift
31+
/// let numbers = Array(1...10)
32+
/// let chunks = numbers.chunks(ofSize: 3)
33+
/// print(chunks)
34+
/// // Output: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
35+
/// ```
36+
///
37+
/// - Example: Processing items in chunks
38+
/// ```swift
39+
/// let tasks = ["Task1", "Task2", "Task3", "Task4"]
40+
/// for chunk in tasks.chunks(ofSize: 2) {
41+
/// for task in chunk {
42+
/// task.perform()
43+
/// }
44+
///
45+
/// print("Processed chunk of tasks: \(chunk)")
46+
/// }
47+
/// // Output:
48+
/// // Processed chunk of tasks: ["Task1", "Task2"]
49+
/// // Processed chunk of tasks: ["Task3", "Task4"]
50+
/// ```
51+
public func chunks(ofSize size: Int) -> [[Element]] {
52+
guard size > 0 else { fatalError("Chunk size must be greater than 0.") }
53+
54+
var result: [[Element]] = []
55+
var chunk: [Element] = []
56+
var count = 0
57+
58+
for element in self {
59+
chunk.append(element)
60+
count += 1
61+
if count == size {
62+
result.append(chunk)
63+
chunk.removeAll(keepingCapacity: true)
64+
count = 0
65+
}
66+
}
67+
68+
if !chunk.isEmpty {
69+
result.append(chunk)
70+
}
71+
72+
return result
73+
}
2174
}
2275

2376
extension Collection where Element: DivisibleArithmetic {

Tests/HandySwiftTests/Extensions/CollectionExtTests.swift

+9-4
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,22 @@ class CollectionExtTests: XCTestCase {
2626
let intArray = [1, 2, 10]
2727
XCTAssertEqual(intArray.average(), 4.333, accuracy: 0.001)
2828

29-
#if canImport(CoreGraphics)
29+
#if canImport(CoreGraphics)
3030
let averageAsCGFloat: CGFloat = intArray.average()
3131
XCTAssertEqual(averageAsCGFloat, 4.333, accuracy: 0.001)
32-
#endif
32+
#endif
3333

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

37-
#if canImport(CoreGraphics)
37+
#if canImport(CoreGraphics)
3838
let cgFloatArray: [CGFloat] = [1.0, 2.0, 10.0]
3939
XCTAssertEqual(cgFloatArray.average(), 4.333, accuracy: 0.001)
40-
#endif
40+
#endif
41+
}
42+
43+
func testChunks() {
44+
XCTAssertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].chunks(ofSize: 3), [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]])
45+
XCTAssertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].chunks(ofSize: 5), [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
4146
}
4247
}

0 commit comments

Comments
 (0)