使用underscore.js将两个(或更多)数组映射为一个数组

10
我需要对多个数组进行逐个元素相加。也就是说,我有多个长度相同的数组,我需要一个具有相同元素数量的数组,这些元素是输入的和。Underscore可以将所有元素折叠成一个元素,并使用函数映射每个元素,但我找不到任何方法将两个数组按部分组合在一起。
如果我的原始数组是[1,2,3,4,5,6][1,1,1,1,1,1][2,2,2,2,2,2],则结果应该是[4,5,6,7,8,9]
我知道可以通过迭代数组来完成,但想知道是否可以使用underscore.js函数更轻松/更快地完成。我能做到吗?怎么做?
5个回答

11
更容易,但不一定更快。要模拟一个 zipWith,您可以将 zip 与求和-reduce 结合起来:
var arrays = [[1,2,3,4,5,6], [1,1,1,1,1,1], [2,2,2,2,2,2]];

_.map(_.zip.apply(_, arrays), function(pieces) {
     return _.reduce(pieces, function(m, p) {return m+p;}, 0);
});

太完美了。它在我所有的场景中都能正常工作,并且速度足够快。我将对其进行基准测试,但看起来很棒。谢谢。 - David Pardo
@Bergi,我不理解apply(_,符号。这个下划线js函数与哪个相关? - Stephane Rolland
@StephaneRolland: _ 这里是 Underscore 对象本身。查看 fn.apply 如何处理参数... 实际上我们也可以在这里传递 null - Bergi

4
你可以使用 lodash (https://lodash.com/) 代替 underscore,它有一个非常酷的 zipWith (https://lodash.com/docs#zipWith) 操作符,可以像下面的示例一样工作。 (注意 _.add 也是 lodash 的数学函数)
var a = [1,2,3,4,5,6]
  , b = [1,1,1,1,1,1]
  , c = [2,2,2,2,2,2];

var result = _.zipWith(a, b, c, _.add);

// result = [4, 5, 6, 7, 8, 9]

Lodash 4 已经改变了 _.unzipWith 的工作方式,使用 (...group) 进行执行。而在 v3 中,被 zipWith 使用的 unzipWith 使用 (accumulator, value, index, group) 执行其迭代器。 - Penny Liu

4

我认为使用下划线并不能让它更容易。以下是两个选项:

var a = [1,2,3,4,5,6]
  , b = [1,1,1,1,1,1]
  , c = [2,2,2,2,2,2];

var result = a.map(function(_,i) {
  return a[i] + b[i] + c[i];
});

// OR

var result = [];
for (var i = 0; i < a.length; i++) {
  result.push(a[i] + b[i] + c[i]);
}

console.log(result); //=> [4,5,6,7,8,9]

1
我现在正在使用第二个版本。唯一的问题是,虽然它对于两三个数组来说运行良好,但当有更多数组时,在概念上受到限制。我的原始想法是构建一个数组的数组,并以某种方式将它们全部映射到每个元素。无论如何,你的第一个解决方案看起来很有前途。我打算尝试扩展它。 - David Pardo

0

使用Lodash 4

var arrays = [
  [1, 2, 3, 4, 5, 6],
  [1, 1, 1, 1, 1, 1],
  [2, 2, 2, 2, 2, 2]
];

var result = _.map(_.unzip(arrays), _.sum);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>


0
你可以将zip与map和reduce结合使用: 尚未测试,但类似这样的代码可能会起作用。
var result = _.map(_.zip(array1, array2, array3),function(zipped){return _.reduce(zipped,  function(memo, num){ return memo + num; }, 0)});

第一个下划线后面缺少了一个点 :)。你的解决方案几乎与Bergi编写的相同,但是使用zip而不是zip._apply并不能给我正确的答案。我需要回到文档中找原因。非常感谢。 - David Pardo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接