假设我有一个数组的数组,就像这样:
[
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
]
在javascript中,如何生成一个新的数组,该数组将内部数组每个位置的所有值相加? 在这种情况下,结果将是:[17, 10, 19]。我需要能够拥有适用于内部数组长度的解决方案。我认为可以使用map和for-of的某些组合,或可能是reduce,但我无法完全理解它。我已经搜索过了,但找不到与此完全匹配的示例。
假设我有一个数组的数组,就像这样:
[
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
]
在javascript中,如何生成一个新的数组,该数组将内部数组每个位置的所有值相加? 在这种情况下,结果将是:[17, 10, 19]。我需要能够拥有适用于内部数组长度的解决方案。我认为可以使用map和for-of的某些组合,或可能是reduce,但我无法完全理解它。我已经搜索过了,但找不到与此完全匹配的示例。
Array.prototype.reduce()
与 Array.prototype.forEach()
结合使用。
var array = [
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
],
result = array.reduce(function (r, a) {
a.forEach(function (b, i) {
r[i] = (r[i] || 0) + b;
});
return r;
}, []);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
通过使用一个映射来缩短数组,可以更新更简洁的方法。
var array = [[0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3]],
result = array.reduce((r, a) => a.map((b, i) => (r[i] || 0) + b), []);
console.log(result);
使用Lodash 4:
function sum_columns(data) {
return _.map(_.unzip(data), _.sum);
}
var result = sum_columns([
[1, 2],
[4, 8, 16],
[32]
]);
console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Lodash 4已经改变了_.unzipWith
的工作方式,现在迭代器一次性获取传递的所有值,因此我们不能再使用缩减器样式的_.add
。在Lodash 3中,以下示例可以正常工作:
function sum_columns(data) {
return _.unzipWith(data, _.add);
}
var result = sum_columns([
[1, 2],
[4, 8, 16],
[32],
]);
console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
_.unzipWith
会在某行比其他行短的情况下插入undefined
,而_.sum
将未定义的值作为0处理。(自Lodash 3起)
如果您的输入数据可能包含undefined
和null
项,并且希望将它们视为0,则可以使用此选项:
function sum_columns_safe(data) {
return _.map(_.unzip(data), _.sum);
}
function sum_columns(data) {
return _.unzipWith(data, _.add);
}
console.log(sum_columns_safe([[undefined]])); // [0]
console.log(sum_columns([[undefined]])); // [undefined]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
这段代码适用于 Lodash 3 版本,不幸的是在 Lodash 4 中,我没有找到一种好的方式将 undefined 视为 0 进行处理,因为现在 sum 已经被更改了,所以 _.sum([undefined]) === undefined
flatten()
吗? - binki_.map(_.unzip([[undefined]]), _.sum) -> [0]
,但是 _.unzipWith([[undefined]], _.add) === [undefined]
。 - Tamas Hegedus4.17.11
中,我得到了不同的结果[5,10,16]
,而不是[37,10,16]
。 - Penny Liu使用 ES6
中的一行代码,结合 map
和 reduce
var a = [ [0, 1, 3], [2, 4, 6], [5, 5, 7], [10, 0, 3] ];
var sum = a[0].map((_, i) => a.reduce((p, _, j) => p + a[j][i], 0));
document.write(sum);
function totalIt (arr) {
var lng = arr[0].length;
return [].concat.apply([],arr) //flatten the array
.reduce( function(arr, val, ind){ //loop over and create a new array
var i = ind%lng; //get the column
arr[i] = (arr[i] || 0) + val; //update total for column
return arr; //return the updated array
}, []); //the new array used by reduce
}
var arr = [
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
];
console.log(totalIt(arr)); //[17, 10, 19]
a = [
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
]
b = []
for(i = 0; i < a[0].length; i++){
count = 0
for(j = 0; j < a.length; j++){
count += a[j][i]
}
b.push(count)
}
console.log(b)
到目前为止,还没有使用问题中提到的for ... of
得到答案。
我已经使用了条件语句来处理不同长度的内部数组。
var a = [
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
];
i = 0;
r = []
for (const inner of a) {
j = 0;
for (const num of inner) {
if (j == r.length) r.push(num)
else r[j] += num
j++;
}
i++;
}
console.log(r);
在这种情况下,经典的for
循环比for ... of
更适合。
以下代码片段使用条件(三元)运算符。
var a = [
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
];
r = [];
for (i = 0; i < a.length; i++) {
for (j = 0; j < a[i].length; j++) {
j==r.length ? r.push(a[i][j]) : r[j]+=a[i][j]
}
}
console.log(r);
var array = [
[0],
[2, 4],
[5, 5, 7, 10, 20, 30],
[10, 0]
];
b = Array(array.reduce((a, b) => Math.max(a, b.length), 0)).fill(0);
result = array.reduce((r, a) => b.map((_, i) => (a[i] || 0) + (r[i] || 0)), []);
console.log(result);
const ar = [
[0, 1, 3],
[2, 4, 6],
[5, 5, 7],
[10, 0, 3]
]
ar.map( item => item.reduce( (memo, value)=> memo+= value, 0 ) )
//result-> [4, 12, 17, 13]
0
? - jfriend00