javascript中是否有类似于Python的zip函数?也就是说,给定多个相等长度的数组,创建一个由对组成的数组。

例如,如果我有三个这样的数组:

var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];

输出数组应该是:

var outputArray = [[1,'a',4], [2,'b',5], [3,'c',6]]

当前回答

我创建了一个简单的函数,通过一个选项来提供一个拉链函数

function zip(zipper, ...arrays) {
    if (zipper instanceof Array) {
        arrays.unshift(zipper)
        zipper = (...elements) => elements
    }

    const length = Math.min(...arrays.map(array => array.length))
    const zipped = []

    for (let i = 0; i < length; i++) {
        zipped.push(zipper(...arrays.map(array => array[i])))
    }

    return zipped
}

https://gist.github.com/AmrIKhudair/4b740149c29c492859e00f451832975b

其他回答

Python有两个压缩序列的函数:zip和itertools.zip_longest。Javascript中相同功能的实现如下所示:

Python的zip在JS/ES6上的实现

const zip = (...arrays) => {
    const length = Math.min(...arrays.map(arr => arr.length));
    return Array.from({ length }, (value, index) => arrays.map((array => array[index])));
};

结果:

console.log(zip(
    [1, 2, 3, 'a'],
    [667, false, -378, '337'],
    [111],
    [11, 221]
));

[[1, 667, 111, 11]

console.log(zip(
    [1, 2, 3, 'a'],
    [667, false, -378, '337'],
    [111, 212, 323, 433, '1111']
));

[[1、667、111],[2,假的,212年],[3、-378、323],[' a ', “337”,433]]

console.log(zip(
    [1, 2, 3, 'a'],
    [667, false, -378, '337'],
    [111],
    []
));

[]

Python的zip_longest在JS/ES6上的实现

(https://docs.python.org/3.5/library/itertools.html?highlight=zip_longest # itertools.zip_longest)

const zipLongest = (placeholder = undefined, ...arrays) => {
    const length = Math.max(...arrays.map(arr => arr.length));
    return Array.from(
        { length }, (value, index) => arrays.map(
            array => array.length - 1 >= index ? array[index] : placeholder
        )
    );
};

结果:

console.log(zipLongest(
    undefined,
    [1, 2, 3, 'a'],
    [667, false, -378, '337'],
    [111],
    []
));

[[1,667, 111, undefined], [2, false, undefined, undefined], [3, -378, undefined, undefined], ['a', '337', undefined, 未定义

console.log(zipLongest(
    null,
    [1, 2, 3, 'a'],
    [667, false, -378, '337'],
    [111],
    []
));

[[1, 667, 111, null], [2, false, null, null], [3, -378, Null, Null], ['a', '337', Null, Null]]

console.log(zipLongest(
    'Is None',
    [1, 2, 3, 'a'],
    [667, false, -378, '337'],
    [111],
    []
));

[[1,667, 111, 'Is None'], [2, false, 'Is None', 'Is None'], [3, -378,“没有”,“没有 ' ], [ ' ”、“337”、“没有”、“ 没有']]

您可以减少数组的数组,并通过获取内部数组的索引的结果来映射新数组。

Var array1 = [1,2,3], Array2 = ['a','b','c'], Array3 = [4,5,6], 数组= [array1, array2, array3], 转置=数组。减少((r) = > a.map ((v, i) = > (r(我)| | []).concat (v)), []); console.log(转置);

有趣的传播。

常量 转置= (r, a) => a.map((v, i) =>[…](r[i] || []), v]), Array1 = [1,2,3], Array2 = ['a','b','c'], Array3 = [4,5,6], 转置= [array1, array2, array3]。减少(转置,[]); console.log(转置);

ES2020最短变体:

function * zip(arr1, arr2, i = 0) {
  while(arr1[i] || arr2[i]) yield [arr1[i], arr2[i++]].filter(x => !!x);
}
    
[ ...zip(arr1, arr2) ]  // result

Mochikit库提供了这个函数和许多其他类似python的函数。Mochikit的开发者也是一个Python爱好者,所以它具有Python的一般风格,并且还将异步调用包装在一个扭曲的框架中。

惰性生成器解决方案的一个变体:

function* iter(it) { yield* it; } function* zip(...its) { its = its.map(iter); while (true) { let rs = its.map(it => it.next()); if (rs.some(r => r.done)) return; yield rs.map(r => r.value); } } for (let r of zip([1,2,3], [4,5,6,7], [8,9,0,11,22])) console.log(r.join()) // the only change for "longest" is some -> every function* zipLongest(...its) { its = its.map(iter); while (true) { let rs = its.map(it => it.next()); if (rs.every(r => r.done)) return; yield rs.map(r => r.value); } } for (let r of zipLongest([1,2,3], [4,5,6,7], [8,9,0,11,22])) console.log(r.join())

这是python经典的“n-group”习语zip(*[iter(a)]*n):

triples = [...zip(...Array(3).fill(iter(a)))]