2016年更新:
这是一个时髦的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版本的参数列表是可变参数不同。如果需要所有这些 “功能”,请参见下文。它只需要多花两行代码。
下面的代码将模仿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数组推导或生成器。)