在Javascript中,如果我有一个表示矩阵的数组数组,请说
x = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
横向总结""很简单,可以像
一样完成x.map(function(y){
return y.reduce(function(a,b){
return a+b;
});
});
现在我想计算"垂直"总和,可以做到
x.reduce(function(a, b){
return a.map(function(v,i){
return v+b[i];
});
});
但我对这个版本并不满意,我希望有更好,更优雅,更直接的东西。也许预先转换矩阵的简单方法?任何人吗?
请注意,几天前我问了一个类似的问题(link)但是缺乏更大的影响。
答案 0 :(得分:12)
您可以对同一索引处的值求和。
使用: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));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:5)
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];
});
});
为了我自己的利益,并希望其他人受益,我想解释嵌套的reduce
/ map
方法如何用于执行等长数组数组的垂直求和。这是OP提供的完全可接受的版本。
reduce
方法对累加器应用函数,并从左到右对数组的每个值应用,以将其减少为单个值(MDN)。
在本例的情况下,在第一次迭代中,前两个数组作为reduce
和array1
传递给array2
的回调函数。回调函数的返回值是应用于array1的map
方法的结果。
map
返回一个新数组,其结果是在数组的每个元素上调用提供的函数。 (MDN)。
因此,map
会迭代array1
中的每个值,并将其添加到同一索引位置的array2
中的值。这些结果被推送到一个新数组,然后返回到reduce
方法。
刚刚返回的总和数组成为新array1
,reduce
调用其函数传入新array1
,下一个数组作为新array2
重复这一过程,直到我们用完arrayOfArrays
从:
开始arrayOfArrays = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
reduce pass的第一次迭代:
array1 [1,2,3,4]
array2 [5,6,7,8]
到reduce
的回调函数。 reduce
的返回值
是使用map
添加array1
的每个值而派生的新数组
array2
在同一位置的值:
array1 [1,2,3,4]
array2 [5,6,7,8]
return [6,8,10,12]
此值将返回reduce
方法并成为新值
array1
。 array1
和下一个数组(array2
)然后再次传入
reduce
回调函数,并由map
方法求和:
array1 [6,8,10,12]
array2 [9,10,11,12]
return [15,18,21,24] // returned by map()
答案 2 :(得分:2)
我认为你不满意没有原生zip
功能,因为这是你reduce
中map
基本上正在做的事情。您要么自己实现它,要么从像Ramda这样的库中导入它,以便编写如下优雅的代码:
var verticalSum = x.map(R.zipWith(function(a,b){ return a+b; }));
如果您正在寻找一种有效的解决方案,那么基本上没有比显式循环更好的方法。
答案 3 :(得分:1)
非常优雅,仅适用于我的方阵。
x = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
];
var sum = function(arr) {
return arr.reduce(function(a, b){ return a + b; }, 0);
};
x.map(function(row, i) {
return sum(x.map(function(row) { return row[i]; }));
});
http://jsfiddle.net/btux9s2d/控制台日志示例。
任何大小的矩阵,不是那么优雅,但也许会帮助你的方式: http://jsfiddle.net/btux9s2d/2/
答案 4 :(得分:0)
通过此功能,您可以使用递归性对任何维数的数组求和:
function sumRecursiveArray(arr) {
return arr.reduce(function(acc, value) {
return acc + (Array.isArray(value) ? sumRecursiveArray(value) : value);
}, 0);
}
var sum = sumRecursiveArray([[1,1,1],[2,2,2]]);
console.log(sum); // 9
答案 5 :(得分:0)
total