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]]
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* 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)))]
其他回答
和@Brandon一样,我推荐Underscore的zip功能。但是,它的作用类似zip_longest,根据需要附加未定义的值以返回最长输入的长度。
我使用mixin方法用zipshort扩展下划线,它的作用类似于Python的zip,基于库自己的zip源代码。
你可以在你的普通JS代码中添加以下代码,然后像调用下划线一样调用它:_。zipShortest ([1, 2, 3], [a])返回[[1,' ']],例如。
// Underscore library addition - zip like python does, dominated by the shortest list
// The default injects undefineds to match the length of the longest list.
_.mixin({
zipShortest : function() {
var args = Array.Prototype.slice.call(arguments);
var length = _.min(_.pluck(args, 'length')); // changed max to min
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(args, "" + i);
}
return results;
}});
查看下划线库。
Underscore提供了超过100个函数,这些函数既支持你最喜欢的日常函数帮助:映射、过滤器、调用——也支持更专业的功能:函数绑定、javascript模板、创建快速索引、深度等式测试等等。
-说说制作它的人
我最近开始专门为zip()函数使用它,它给我留下了很好的第一印象。我使用jQuery和CoffeeScript,它只是完美地与他们。下划线就在他们离开的地方,到目前为止,它还没有让我失望。哦,顺便说一下,它只缩小了3kb。
看看吧:
_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
// returns [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
这将从Ddi基于迭代器的答案中删除一行:
function* zip(...toZip) {
const iterators = toZip.map((arg) => arg[Symbol.iterator]());
const next = () => toZip = iterators.map((iter) => iter.next());
while (next().every((item) => !item.done)) {
yield toZip.map((item) => item.value);
}
}
没有等价的函数。如果你只有几个数组,你应该使用for循环获取一个索引,然后使用索引访问数组:
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
for (let i = 0; i < Math.min(array1.length, array2.length); i++) {
doStuff(array1[i], array2[i]);
}
如果你有更多的数组,你可以在数组上有一个内循环。
Mochikit库提供了这个函数和许多其他类似python的函数。Mochikit的开发者也是一个Python爱好者,所以它具有Python的一般风格,并且还将异步调用包装在一个扭曲的框架中。