这是一个时髦的Ecmascript 6版本:
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
相当于插图。到
Python { zip(*args)}:> zip([['row0col0', 'row0col1', 'row0col2'], ['row1col0', 'row1col1', 'row1col2']]);[["row0col0","row1col0"], ["row0col1","row1col1"], ["row0col2","row1col2"]]
(并且
FizzyTea指出ES6具有可变参数语法,因此以下函数定义将类似于python,但请参见下文的免责声明…这将不是其自身的逆,因此
zip(zip(x))将不相等x;尽管正如Matt Kramer指出的那样
zip(...zip(...x))==x(例如在常规python中
zip(*zip(*x))==x))
等效定义 到
Python { zip}:> 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
(请注意,…语法可能在此时以及将来可能会出现性能问题,因此,如果将第二个答案与可变参数一起使用,则可能要进行性能测试。)
这里是一个班轮:
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(...)上面假设数组的大小相等,应该是相等的。它还假定你传入一个lists参数列表,这与Python版本的参数列表是可变参数不同。如果需要所有这些 “功能”,请参见下文。它仅需要大约2行代码。
下面的代码将模仿Python zip在数组大小不等的极端情况下的行为,默默地假装数组的较长部分不存在:
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()// []这将模仿Python的
itertools.zip_longest行为,
undefined在未定义数组的地方插入:
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不再是其自身的反函数。要模仿
zip(*[...])Python中的习惯用法,你需要
zip.apply(this, [...])在想要反转zip函数时或者在类似情况下要使用可变数量的列表作为输入时进行操作。
附录:
要使此句柄具有任何可迭代性(例如,在Python中,你可以zip在字符串,范围,地图对象等上使用),可以定义以下内容:
function iterView(iterable) { // returns an array equivalent to the iterable}但是,如果你zip以以下方式编写,则甚至没有必要:
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数组推导或生成器。)



