splitIntoChunks
Splits an array into n
chunks of approximately equal size. Distributes elements as evenly as possible from left to right. If the array cannot be divided equally, earlier chunks will be slightly larger.
1/**
2 * Splits an array into 'n' chunks of approximately equal size.
3 * Distributes elements as evenly as possible from left to right.
4 * If the array cannot be divided equally, earlier chunks will be slightly larger.
5 *
6 * @param arr - The array to split.
7 * @param parts - Number of chunks to split into.
8 * @returns A new array of chunks.
9 */
10export function splitIntoChunks<T>(arr: T[], parts: number): T[][] {
11 if (parts <= 0) throw new Error('Number of parts must be greater than 0');
12
13 const result: T[][] = [];
14 const len = arr.length;
15 let i = 0;
16 while (i < len && parts > 0) {
17 const size = Math.ceil((len - i) / parts--);
18 result.push(arr.slice(i, i + size));
19 i += size;
20 }
21 return result;
22}
Balanced distribution
Unlike fixed-size chunking, this function intelligently splits the array into parts of nearly equal size, ensuring even distribution of elements.
Left-to-right bias
When an even split isn't possible, earlier chunks get the extra items, which is often desirable for UI rendering or progressive processing.
Efficient algorithm
The function calculates chunk sizes dynamically without repeated recalculations or nested loops, keeping performance optimal.
Safe parameter handling
Includes error checking to prevent division by zero or invalid input (e.g.
parts <= 0)
).Pure and non-mutating
Returns a new array without modifying the original input.
Tests | Examples
1test('splitIntoChunks - basic split', () => {
2 expect(splitIntoChunks([1, 2, 3, 4, 5], 2)).toEqual([[1, 2, 3], [4, 5]]);
3});
4
5test('splitIntoChunks - equal chunks', () => {
6 expect(splitIntoChunks([1, 2, 3, 4], 2)).toEqual([[1, 2], [3, 4]]);
7});
8
9test('splitIntoChunks - more parts than elements', () => {
10 expect(splitIntoChunks([1, 2], 5)).toEqual([[1], [2]]);
11});
12
13test('splitIntoChunks - single part', () => {
14 expect(splitIntoChunks([1, 2, 3], 1)).toEqual([[1, 2, 3]]);
15});
16
17test('splitIntoChunks - empty array', () => {
18 expect(splitIntoChunks([], 3)).toEqual([]);
19});
20
21test('splitIntoChunks - invalid parts (zero)', () => {
22 expect(() => splitIntoChunks([1, 2], 0)).toThrow('Number of parts must be greater than 0');
23});
Common Use Cases
UI layout and pagination
Used to divide items into equally filled rows or columns — especially useful for responsive grid layouts or multi-column rendering.
Parallel processing
Distributes work across threads, workers, or services, ensuring that each batch has a fair workload.
Progressive loading
Enables you to group data into progressive chunks (e.g., for lazy-loading or infinite scrolling).
Data visualization
Breaks down large datasets into even chart segments or grouped plots.