Javascript相当于Python的zip功能

问题:

有相当于Python的zip功能吗?也就是说,给定两个相等长度的数组创建一对数组。
例如,如果我有三个数组,如下所示:

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

输出数组应为:

var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]

回答:

 2016更新:
这是一个snazzier Ecmascript 6版本:

zip= rows=>rows[0].map((_,c)=>rows.map(row=>row))

插图:

> zip([['row0col0', 'row0col1', 'row0col2'],
       ['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
 ["row0col1","row1col1"],
 ["row0col2","row1col2"]]

(和FizzyTea指出,ES6具有可变参数语法,所以下面的代码将像python一样运行,但是请看下面的免责声明…这不会是它自己的逆,所以zip(zip(x))不会等于x 🙂

> zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row))
> zip( ['row0col0', 'row0col1', 'row0col2'] ,
       ['row1col0', 'row1col1', 'row1col2'] );
             // note zip(row0,row1), not zip(matrix)
same answer as above

(请注意,...语法可能在这个时候,可能在将来会有性能问题,所以如果您使用第二个答案与可变参数,您可能需要对其进行测试。)
这是一个oneliner:
class=”lang-js prettyprint-override”>

function zip(arrays) {
    return arrays[0].map(function(_,i){
        return arrays.map(function(array){return array[i]})
    });
}

// > zip([[1,2],[11,22],[111,222]])
// [[1,11,111],[2,22,222]]]

// If you believe the following is a valid return value:
//   > zip([])
//   []
// then you can special-case it, or just do
//  return arrays.length==0 ? [] : arrays[0].map(...)

以上假设数组的大小相同,因为它们应该是相同的。它还假设您传递列表参数的单个列表,与参数列表是可变的Python的版本不同。 如果你想要所有这些“功能”,见下文。它只需要2个额外的代码行。
以下将模拟Python的zip行为,在边缘情况下,数组不是相同的大小,默默地假装数组的较长部分不存在:
class=”lang-js prettyprint-override”>

function zip() {
    var args = [].slice.call(arguments);
    var shortest = args.length==0 ? [] : args.reduce(function(a,b){
        return a.length<b.length ? a : b
    });

    return shortest.map(function(_,i){
        return args.map(function(array){return array&#91;i&#93;})
    });
}

// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222]]]

// > zip()
// []

这将模仿Python的itertools.zip_longest行为,插入未定义数组的undefined
class=”lang-js prettyprint-override”>

function zip() {
    var args = [].slice.call(arguments);
    var longest = args.reduce(function(a,b){
        return a.length>b.length ? a : b
    }, []);

    return longest.map(function(_,i){
        return args.map(function(array){return array[i]})
    });
}

// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222],[null,null,333]]

// > zip()
// []

如果你使用这些最后两个版本(也称为多参数版本),那么zip不再是它自己的反向。为了模仿Python中的zip(*[...])成语,当您要反转zip功能时,或者您希望类似地具有可变数目的列表作为输入,则需要执行zip.apply(this, [...])
 附录
为了使这个句柄任何可迭代的(例如,在Python中,您可以对字符串,范围,地图对象等使用zip),您可以定义以下内容:
class=”lang-js prettyprint-override”>

function iterView(iterable) {
    // returns an array equivalent to the iterable
}

但是,如果您在以下way中写入zip,即使这样也不必要:
class=”lang-js prettyprint-override”>

function zip(arrays) {
    return Array.apply(null,Array(arrays[0].length)).map(function(_,i){
        return arrays.map(function(array){return array[i]})
    });
}

演示:

> JSON.stringify( zip(['abcde',[1,2,3,4,5]]) )
[["a",1],["b",2],["c",3],["d",4],["e",5]]

(或者你可以使用range(...) Python风格的函数,如果你已经写了一个,最终你将能够使用ECMAScript数组的推导或生成器。)

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Javascript equivalent of Python’s zip function

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

49 − = 44