denoland / denoland/std

Allow Zip and Unzip to work on more than two arrays

Open
#1,203 6 comments 0 reactions 0 assignees View on GitHub
enhancement help wanted
Dominant language
TypeScript
Stars
3.6k
Forks
681
PR merge metrics
No merged PRs in 30d

Description

Previous discussion for this issue here: https://github.com/denoland/deno_std/discussions/970#discussioncomment-1272939

**Is your feature request related to a problem? Please describe.**
Currently, zip and unzip in std/collections follow this type signature, which means they operate on two arrays in the case of zip or an array of pairs, in the case of unzip.
```ts
function zip(array: readonly T[], withArray: readonly U[]): [T, U][];
function unzip(pairs: readonly [T, U][]): [T[], U[]]
```

**Describe the solution you'd like**
I'd like it if zip could work on more than two arrays at a time, and if unzip could work on more than an array of pairs.

**Describe alternatives you've considered**
There are two ways forward: Either use varargs to accept as many arrays as possible like this and zip them up:
```ts
function variadicZip(...arrays: (readonly T[])[]): T[] {
const arrLength = arrays.map(i => i.length);

const returnLength = Math.min(...arrLength);

const ret = new Array(returnLength);

for (let i = 0; i < returnLength; i += 1) {
const arr = [];
for (const array of arrays) {
arr.push(array[i]);
}
ret[i] = arr;
}

return ret;
}
```

or to overload zip to take up to 10 arrays and return a zip of the arrays provided (implemented for 2 + 3 arrays). This has the advantage that it provides the caller with more type information (you get back an array of `[T, U][]` if you zip with two arrays, whereas with the previous implementation, you would get back an array of `[any][]`.

```ts
function zip(
array1: readonly T[],
array2: readonly U[]
): [T, U][] {
const returnLength = Math.min(array1.length, array2.length);

const ret = new Array<[T, U]>(returnLength);

for (let i = 0; i < returnLength; i += 1) {
ret[i] = [array1[i], array2[i]];
}

return ret;
}

function zip(
array1: readonly T[],
array2: readonly U[],
array3: readonly V[]
): [T, U, V][] {
const returnLength = Math.min(...[array1.length, array2.length, array3.length]);

const ret = new Array<[T, U, V]>(returnLength);

for (let i = 0; i < returnLength; i += 1) {
ret[i] = [array1[i], array2[i], array3[i]];
}

return ret;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.