diff --git a/Data-Structures/Array/Chunk.js b/Data-Structures/Array/Chunk.js new file mode 100644 index 0000000000..58d74c9aac --- /dev/null +++ b/Data-Structures/Array/Chunk.js @@ -0,0 +1,26 @@ +/** + * @function chunk + * @description Splits an array into smaller arrays of a specified size. + * The last chunk may be smaller if the array doesn't divide evenly. + * @param {Array} arr - The input array to chunk + * @param {number} size - The size of each chunk + * @returns {Array} - An array of chunks + * @see https://en.wikipedia.org/wiki/Chunking_(computing) + * @example chunk([1, 2, 3, 4, 5], 2) => [[1, 2], [3, 4], [5]] + * @example chunk([1, 2, 3], 3) => [[1, 2, 3]] + */ +const chunk = (arr, size) => { + if (!Array.isArray(arr)) { + throw new TypeError('First argument must be an array') + } + if (!Number.isInteger(size) || size < 1) { + throw new TypeError('Size must be a positive integer') + } + const result = [] + for (let i = 0; i < arr.length; i += size) { + result.push(arr.slice(i, i + size)) + } + return result +} + +export { chunk } diff --git a/Data-Structures/Array/test/Chunk.test.js b/Data-Structures/Array/test/Chunk.test.js new file mode 100644 index 0000000000..9e78063617 --- /dev/null +++ b/Data-Structures/Array/test/Chunk.test.js @@ -0,0 +1,59 @@ +import { chunk } from '../Chunk.js' + +describe('chunk', () => { + test('chunk([1,2,3,4,5], 2) returns [[1,2],[3,4],[5]]', () => { + expect(chunk([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]) + }) + + test('chunk([1,2,3], 3) returns [[1,2,3]]', () => { + expect(chunk([1, 2, 3], 3)).toEqual([[1, 2, 3]]) + }) + + test('chunk([1,2,3,4], 2) returns [[1,2],[3,4]]', () => { + expect(chunk([1, 2, 3, 4], 2)).toEqual([ + [1, 2], + [3, 4] + ]) + }) + + test('chunk with size 1 returns array of single elements', () => { + expect(chunk([1, 2, 3], 1)).toEqual([[1], [2], [3]]) + }) + + test('chunk empty array returns empty array', () => { + expect(chunk([], 2)).toEqual([]) + }) + + test('chunk with size larger than array returns one chunk', () => { + expect(chunk([1, 2, 3], 10)).toEqual([[1, 2, 3]]) + }) + + test('chunk does not mutate original array', () => { + const arr = [1, 2, 3, 4] + chunk(arr, 2) + expect(arr).toEqual([1, 2, 3, 4]) + }) + + test('chunk works with strings', () => { + expect(chunk(['a', 'b', 'c', 'd'], 2)).toEqual([ + ['a', 'b'], + ['c', 'd'] + ]) + }) + + test('throws TypeError for non-array input', () => { + expect(() => chunk('123', 2)).toThrow(TypeError) + }) + + test('throws TypeError for size 0', () => { + expect(() => chunk([1, 2, 3], 0)).toThrow(TypeError) + }) + + test('throws TypeError for negative size', () => { + expect(() => chunk([1, 2, 3], -1)).toThrow(TypeError) + }) + + test('throws TypeError for float size', () => { + expect(() => chunk([1, 2, 3], 1.5)).toThrow(TypeError) + }) +})