Allow Zip and Unzip to work on more than two arrays
- 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
Assessment
This issue has not been assessed yet.