<p><strong>2016更新:</strong></p>
<p>下面是一个时髦的Ecmascript 6版本:</p>
<pre><code>zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
</code></pre>
<p>相当于Python的插图:</p>
<pre><code>> zip([['row0col0', 'row0col1', 'row0col2'],
['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
["row0col1","row1col1"],
["row0col2","row1col2"]]
</code></pre>
<p>(FizzyTea指出ES6有可变的参数语法,所以下面的函数定义将像python一样,但是请参见下面的免责声明。。。这不是它自己的逆命题,因此<code>zip(zip(x))</code>将不等于<code>x</code>;尽管正如Matt Kramer指出的<code>zip(...zip(...x))==x</code>(就像在普通python中一样<code>zip(*zip(*x))==x</code>)</p>
<p>另一种定义,相当于Python</em></strong>{<code>zip</code>:</p>
<pre><code>> zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]))
> zip( ['row0col0', 'row0col1', 'row0col2'] ,
['row1col0', 'row1col1', 'row1col2'] );
// note zip(row0,row1), not zip(matrix)
same answer as above
</code></pre>
<p>(请注意,<code>...</code>语法此时可能会有性能问题,将来也可能会有性能问题,因此如果将第二个答案与可变参数一起使用,则可能需要对其进行性能测试。)</p>
<hr/>
<p>这是一条单行线:</p>
<pre class="lang-js prettyprint-override"><code>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(...)
</code></pre>
<hr/>
<p>上面的假设是数组的大小应该是相等的。它还假设您传入一个列表参数列表,这与Python版本中参数列表是可变的不同。<strong>如果您想要所有这些功能,请参见下文。只需要额外的两行代码。</p>
<p>下面将模拟Python在数组大小不相等的边缘情况下的<code>zip</code>行为,静默地假装数组的较长部分不存在:</p>
<pre class="lang-js prettyprint-override"><code>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[i]})
});
}
// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222]]]
// > zip()
// []
</code></pre>
<p>这将模拟Python的<code>itertools.zip_longest</code>行为,在未定义数组的地方插入<code>undefined</code>:</p>
<pre class="lang-js prettyprint-override"><code>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()
// []
</code></pre>
<p>如果你使用最后两个版本(variadic aka。多个参数版本),那么zip就不再是它自己的逆了。要模拟Python中的<code>zip(*[...])</code>习惯用法,当您想要反转zip函数或类似地希望将可变数量的列表作为输入时,您需要执行<code>zip.apply(this, [...])</code>。</p>
<hr/>
<p><strong>附录</strong>:</p>
<p>要使此句柄成为任何可iterable(例如,在Python中,可以对字符串、范围、映射对象等使用<code>zip</code>),可以定义以下内容:</p>
<pre class="lang-js prettyprint-override"><code>function iterView(iterable) {
// returns an array equivalent to the iterable
}
</code></pre>
<p>但是,如果您在下面的<a href="https://stackoverflow.com/a/13735425/711085">way</a>中编写<code>zip</code>,即使这样也没有必要:</p>
<pre class="lang-js prettyprint-override"><code>function zip(arrays) {
return Array.apply(null,Array(arrays[0].length)).map(function(_,i){
return arrays.map(function(array){return array[i]})
});
}
</code></pre>
<p>演示:</p>
<pre><code>> JSON.stringify( zip(['abcde',[1,2,3,4,5]]) )
[["a",1],["b",2],["c",3],["d",4],["e",5]]
</code></pre>
<p>(或者,如果您已经编写了Python风格的函数,则可以使用该函数。最终,您将能够使用ECMAScript数组理解或生成器。)</p>