Joh*_*ohn 5 javascript arrays functional-programming data-structures
在Javascript中,如果我有一个表示矩阵的数组数组,比如说
x = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
Run Code Online (Sandbox Code Playgroud)
将它"水平"相加很容易就可以完成
x.map(function(y){
return y.reduce(function(a,b){
return a+b;
});
});
Run Code Online (Sandbox Code Playgroud)
现在我想计算"垂直"总和,这可以做到
x.reduce(function(a, b){
return a.map(function(v,i){
return v+b[i];
});
});
Run Code Online (Sandbox Code Playgroud)
但我对这个版本不满意,我希望有更好,更优雅,更直接的东西.也许预先转换矩阵的简单方法?任何人?
请注意,几天前我问了一个类似的问题(链接)但是缺乏更大的图景.
Nin*_*olz 13
您可以对同一索引处的值求和.
使用: array.reduce(sum)
var sum = (r, a) => r.map((b, i) => a[i] + b);
console.log([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]].reduce(sum));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)
arrayOfArrays = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
arrayOfArrays.reduce(function(array1, array2) {
return array1.map(function(value, index) {
return value + array2[index];
});
});
Run Code Online (Sandbox Code Playgroud)
为了我自己的利益,也希望其他人的利益,我想解释一下嵌套reduce
/ map
方法如何执行等长数组的垂直求和。这是OP提供的完全可接受的版本。
该reduce
方法对一个累加器应用一个函数,并从左到右对数组的每个值应用以将其减少为单个值(MDN)。
在此示例的情况下,在第一次迭代中,将前两个数组传递给reduce
as array1
和的回调函数array2
。回调函数的返回值是map
应用于array1 的方法的结果。
map
返回一个新数组,并在该数组的每个元素上调用提供的函数。(MDN)。
因此,map
迭代每个值array1
并将其添加到array2
同一索引位置的值中。这些结果被推到一个新的数组,然后返回到该reduce
方法。
现在,刚刚返回的总和数组成为new,array1
并reduce
调用其函数,并传入new array1
和下一个array作为new array2
。
重复此过程,直到我们用完数组 arrayOfArrays
从...开始:
arrayOfArrays = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
Run Code Online (Sandbox Code Playgroud)
reduce遍历的第一次迭代:
array1 [1,2,3,4]
array2 [5,6,7,8]
Run Code Online (Sandbox Code Playgroud)
到的回调函数reduce
。的返回值reduce
是一个新数组,通过使用map
来将的每个值array1
加到array2
同一位置的值上而得出:
array1 [1,2,3,4]
array2 [5,6,7,8]
return [6,8,10,12]
Run Code Online (Sandbox Code Playgroud)
此值返回到reduce
方法,并成为新值
array1
。array1
然后将下一个数组(array2
)再次传递给
reduce
回调函数,并通过map
方法求和:
array1 [6,8,10,12]
array2 [9,10,11,12]
return [15,18,21,24] // returned by map()
Run Code Online (Sandbox Code Playgroud)
我认为您对没有本机zip
函数感到不满,因为这就是您的reduce
inmap
本质上所做的事情。您要么必须自己实现它,要么从Ramda这样的库导入它,以便编写如下优雅的代码:
var verticalSum = x.map(R.zipWith(function(a,b){ return a+b; }));
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找有效的解决方案,基本上没有比显式循环更好的方法了。