diff --git a/Data-Structures/Array/Zip.js b/Data-Structures/Array/Zip.js new file mode 100644 index 0000000000..884622c0f4 --- /dev/null +++ b/Data-Structures/Array/Zip.js @@ -0,0 +1,25 @@ +/** + * @function zip + * @description Creates an array of grouped elements where the first element + * contains the first elements of the given arrays, the second element + * contains the second elements, and so on. + * @param {...Array} arrays - Two or more arrays to zip together + * @returns {Array} - Array of grouped elements + * @see https://en.wikipedia.org/wiki/Convolution_(computer_science) + * @example zip([1, 2], ['a', 'b']) => [[1, 'a'], [2, 'b']] + * @example zip([1, 2, 3], ['a', 'b', 'c'], [true, false, true]) => [[1, 'a', true], [2, 'b', false], [3, 'c', true]] + */ +const zip = (...arrays) => { + if (arrays.length === 0) { + throw new TypeError('At least one array must be provided') + } + if (!arrays.every((arr) => Array.isArray(arr))) { + throw new TypeError('All arguments must be arrays') + } + const minLength = Math.min(...arrays.map((arr) => arr.length)) + return Array.from({ length: minLength }, (_, i) => + arrays.map((arr) => arr[i]) + ) +} + +export { zip } diff --git a/Data-Structures/Array/test/Zip.test.js b/Data-Structures/Array/test/Zip.test.js new file mode 100644 index 0000000000..06f17807d8 --- /dev/null +++ b/Data-Structures/Array/test/Zip.test.js @@ -0,0 +1,48 @@ +import { zip } from '../Zip.js' + +describe('zip', () => { + test("zip([1,2],['a','b']) returns [[1,'a'],[2,'b']]", () => { + expect(zip([1, 2], ['a', 'b'])).toEqual([ + [1, 'a'], + [2, 'b'] + ]) + }) + + test('zip three arrays', () => { + expect(zip([1, 2], ['a', 'b'], [true, false])).toEqual([ + [1, 'a', true], + [2, 'b', false] + ]) + }) + + test('zip truncates to shortest array', () => { + expect(zip([1, 2, 3], ['a', 'b'])).toEqual([ + [1, 'a'], + [2, 'b'] + ]) + }) + + test('zip single array returns array of single element arrays', () => { + expect(zip([1, 2, 3])).toEqual([[1], [2], [3]]) + }) + + test('zip with empty array returns empty array', () => { + expect(zip([], [1, 2, 3])).toEqual([]) + }) + + test('zip does not mutate original arrays', () => { + const arr1 = [1, 2] + const arr2 = ['a', 'b'] + zip(arr1, arr2) + expect(arr1).toEqual([1, 2]) + expect(arr2).toEqual(['a', 'b']) + }) + + test('throws TypeError when no arguments provided', () => { + expect(() => zip()).toThrow(TypeError) + }) + + test('throws TypeError for non-array argument', () => { + expect(() => zip([1, 2], 'ab')).toThrow(TypeError) + }) +})