question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow Zip and Unzip to work on more than two arrays

See original GitHub issue

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.

function zip<T, U>(array: readonly T[], withArray: readonly U[]): [T, U][];
function unzip<T, U>(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:

function variadicZip<T = any>(...arrays: (readonly T[])[]): T[] {
    const arrLength = arrays.map(i => i.length);

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

    const ret = new Array<any>(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][].

function zip<T, U>(
  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<T, U, V>(
  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;
}

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
Aplet123commented, Oct 5, 2021

There’s no need for a compromise here, it’s very possible to have well-typed variadic zips:

function variadicZip<T extends unknown[]>(...arrays: {[K in keyof T]: T[K][]}): T[] {
    const arrLength = arrays.map(i => i.length);

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

    const ret: T[] = 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 as T;
    }

    return ret;
}

// foo is [number, string, boolean][]
const foo = variadicZip([1, 2, 3], ["a", "b", "c"], [false, true, true]);
0reactions
Aplet123commented, Oct 11, 2021

@Takashiidobe I found that your implementation incorrectly infers foo to be [number[], string[], boolean[]] when I put it into my example.

Variadic unzip could be typed as such:

function variadicUnzip<T extends unknown[]>(tuples: T[]): {[K in keyof T]: T[K][]} { /* impl */ }

However, it might end up being a breaking change, since [] would no longer unzip to [[], []].

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I zip two arrays in JavaScript? - Stack Overflow
Use the map method: var a = [1, 2, 3] var b = ['a', 'b', 'c'] var c = a.map(function(e, i) { return...
Read more >
Using the Python zip() Function for Parallel Iteration
zip () can receive multiple iterables as input. It returns an iterator that can generate tuples with paired elements from each argument. The...
Read more >
Add Various Zip-Related Types and Operations - Swift Forums
In functional programming, zip and unzip are irreplaceable operations. zip maps an n-tuple of sequences to a sequence of n-tuples.
Read more >
How To Work With Zip Files in Node.js - DigitalOcean
In this step, you'll read and extract all contents in a ZIP archive into a directory. To extract a ZIP archive, you'll instantiate...
Read more >
Best methods for unzipping files in Node.js - LogRocket Blog
Learn the best methods for zipping and unzipping files in Node.js using the decompress, adm-zip, zlib, unzipper, and jszip packages.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found