Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to type define a zip function in typescript

Say I want to create a zip function:

function zip(arrays){
    // assume more than 1 array is given and all arrays 
    // share the same length
    const len = arrays[0].length;
    const toReturn = new Array(len);
    for (let i = 0; i < len; i++){
        toReturn[i] = arrays.map(array=>array[i]);
    }
    return toReturn;
}

console.log(zip([
    [1,2,3],
    [4,5,6],
    [7,8,9],
    [10,11,12],
]));
/*
Output:
(3) [Array(4), Array(4), Array(4)]
0: (4) [1, 4, 7, 10]
1: (4) [2, 5, 8, 11]
2: (4) [3, 6, 9, 12]
*/

In order to type define this function when all arrays hold the same type of elements:

    function zip<T>(arrays: T[][]): T[][]{/* codes omited here */}

However, when arrays are of different types of elements, I get confused about how to use generic type to finish the type definition.

    const zipedResult = zip([[1,2,3],[true,false,true],['a','b','c']]);
    // error raises: Type 'false' is not assignable to type 'number'.(2322)

what I want is

    [[1,2,3],[true,false,true],['a','b','c']]

could be automatically infered as (number|boolean|string)[][] without writing as (number|boolean|string)[][] or EVEN infered as [number[],boolean[],string[]] and result of zip infered as [number, boolean, string][]

How should I correctly type define zip to fullfill such features?

like image 278
TTY112358 Avatar asked May 31 '20 12:05

TTY112358


People also ask

What does zip() do?

The zip() function combines the contents of two or more iterables. zip() returns a zip object. This is an iterator of tuples where all the values you have passed as arguments are stored as pairs. Python's zip() function takes an iterable—such as a list, tuple, set, or dictionary—as an argument.

What is* in zip python?

The "*" operator unpacks a list and applies it to a function. The zip function takes n lists and creates n-tuple pairs from each element from both lists: zip([iterable, ...]) This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.

What is zip in JavaScript?

The zip() function is used to combine the values of given array with the values of original collection at a given index. In JavaScript, the array is first converted to a collection and then the function is applied to the collection.

Does JavaScript have a Zip function?

js users: if you need a zip function in python to work with tensorflow datasets in Javascript, you can use tf. data. zip() in Tensorflow. js.


1 Answers

Here is an implementation that works for me:

export function zip<T extends unknown[][]>(
  ...args: T
): { [K in keyof T]: T[K] extends (infer V)[] ? V : never }[] {
  const minLength = Math.min(...args.map((arr) => arr.length));
  // @ts-expect-error This is too much for ts
  return range(minLength).map((i) => args.map((arr) => arr[i]));
}

for example zip(["x", "y", "z"], [true, false, true]) has inferred type [string, boolean][]

like image 94
Recursing Avatar answered Sep 22 '22 05:09

Recursing