Skip to content

Commit

Permalink
feat(compat): implement unzip (#770)
Browse files Browse the repository at this point in the history
* feat(compat): implement unzip

* jsdoc

* make lint happy

---------

Co-authored-by: Sojin Park <[email protected]>
  • Loading branch information
D-Sketon and raon0211 authored Nov 1, 2024
1 parent 3a4a81d commit 5b9e965
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
13 changes: 13 additions & 0 deletions benchmarks/performance/unzip.bench.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { bench, describe } from 'vitest';
import { unzip as unzipToolkit_ } from 'es-toolkit';
import { unzip as unzipToolkitCompat_ } from 'es-toolkit/compat';
import { unzip as unzipLodash_ } from 'lodash';

const unzipToolkit = unzipToolkit_;
const unzipToolkitCompat = unzipToolkitCompat_;
const unzipLodash = unzipLodash_;

describe('unzip, small arrays', () => {
Expand All @@ -13,6 +15,13 @@ describe('unzip, small arrays', () => {
]);
});

bench('es-toolkit/compat/unzip', () => {
unzipToolkitCompat([
['a', 1, true],
['b', 2, false],
]);
});

bench('lodash/unzip', () => {
unzipLodash([
['a', 1, true],
Expand All @@ -28,6 +37,10 @@ describe('unzip, large arrays', () => {
unzipToolkit(largeArray);
});

bench('es-toolkit/compat/unzip', () => {
unzipToolkitCompat(largeArray);
});

bench('lodash/unzip', () => {
unzipLodash(largeArray);
});
Expand Down
75 changes: 75 additions & 0 deletions src/compat/array/unzip.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { describe, expect, it } from 'vitest';
import { unzip } from './unzip';
import { zip } from '../../array/zip';

describe('unzip', () => {
const object = {
'an empty array': [[], []],
'2-tuples': [
[
['barney', 'fred'],
[36, 40],
],
[
['barney', 36],
['fred', 40],
],
],
'3-tuples': [
[
['barney', 'fred'],
[36, 40],
[false, true],
],
[
['barney', 36, false],
['fred', 40, true],
],
],
};

Object.entries(object).forEach(([key, pair]) => {
it(`\`_.unzip\` should work with ${key}`, () => {
const actual = unzip(pair[1]);
expect(actual).toEqual(pair[0]);
});
});

it(`\`_.unzip\` should work with tuples of different lengths`, () => {
const pair = [
[
['barney', 36],
['fred', 40, false],
],
[
['barney', 'fred'],
[36, 40],
[undefined, false],
],
];
const actual = unzip(pair[1]) as any;
expect('2' in actual[0]).toBeTruthy();
expect(actual).toEqual([
['barney', 36, undefined],
['fred', 40, false],
]);
});

it(`\`_.unzip\` should support consuming its return value`, () => {
const expected = [
['barney', 'fred'],
[36, 40],
];
// @ts-expect-error - TS doesn't support array types in rest parameters
expect(unzip(zip(...unzip(zip(...expected))))).toEqual(expected);
});

it(`\`_.unzip\` should work with array-like object`, () => {
const array = { 0: { 0: 'a', 1: 1, length: 2 }, 1: { 0: 'b', 1: 2, length: 2 }, length: 2 };
const actual = unzip(array);
expect(actual).toEqual([
['a', 'b'],
[1, 2],
]);
});
});
25 changes: 25 additions & 0 deletions src/compat/array/unzip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { unzip as unzipToolkit } from '../../array/unzip.ts';
import { isArrayLikeObject } from '../predicate/isArrayLikeObject.ts';

/**
* Gathers elements in the same position in an internal array
* from a grouped array of elements and returns them as a new array.
*
* @template T - The type of elements in the nested array.
* @param {T[][] | ArrayLike<ArrayLike<T>> | null | undefined} array - The nested array to unzip.
* @returns {T[][]} A new array of unzipped elements.
*
* @example
* const zipped = [['a', true, 1],['b', false, 2]];
* const result = unzip(zipped);
* // result will be [['a', 'b'], [true, false], [1, 2]]
*/
export function unzip<T>(array: T[][] | ArrayLike<ArrayLike<T>> | null | undefined): T[][] {
if (!isArrayLikeObject(array) || !array.length) {
return [];
}
if (Array.isArray(array)) {
return unzipToolkit(array);
}
return unzipToolkit(Array.from(array, value => Array.from(value)));
}
1 change: 1 addition & 0 deletions src/compat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export { tail } from './array/tail.ts';
export { take } from './array/take.ts';
export { takeRight } from './array/takeRight.ts';
export { uniq } from './array/uniq.ts';
export { unzip } from './array/unzip.ts';
export { without } from './array/without.ts';
export { zipObjectDeep } from './array/zipObjectDeep.ts';

Expand Down

0 comments on commit 5b9e965

Please sign in to comment.