简体   繁体   中英

javascript sum array of arrays of objects together

i have an array with the following format

[
[{year:2015, value:23000, value1:1000},{year:2016,value:1000, value1:2000},{year:2017,value:400, value1:3000}],
[{year:2015, value:10000, value1:1000},{year:2016,value:2000, value1:3000},{year:2017,value:500, value1:2000}],
]

i want to sum them together, in this example, i want to have

[{year:2015,value:33000, value1:2000},{year:2016,value:3000, value1:5000},{year:2017,value:900, value1:5000}]

if there are only two arrays in the array but there maybe more arrays in the bigger array. how can i achieve this? currently, i am not able to figure out a good method. Thanks

Ecmascript5 solution:

 var arr = [ [{year:2015, value:23000, value1:1000},{year:2016,value:1000, value1:2000},{year:2017,value:400, value1:3000}], [{year:2015, value:10000, value1:1000},{year:2016,value:2000, value1:3000},{year:2017,value:500, value1:2000}] ], // summing up values for each `year` years = arr.reduce(function (r, a) { a.forEach(function (o) { y = o.year; if (Array.isArray(r[y])) { r[y][0] += o.value; r[y][1] += o.value1; } else { r[y] = [o.value, o.value1]; } }); return r; }, {}), // constructing the resulting array containing objects with `year` totals result = Object.keys(years).map(function (y) { return {year: y, value: years[y][0], value1: years[y][1]}; }); console.log(result); 

You can loop over the items and add value agains a year number (key) in a map / object.

var data = [
[{year:2015, value:23000},{year:2016,value:1000},{year:2017,value:400}],
[{year:2015, value:10000},{year:2016,value:2000},{year:2017,value:500}],
];

var output = {};

data.forEach(function(item) {
  item.forEach(function(obj) {
    output[obj.year] = (output[obj.year] || 0) + obj.value;
  });
});
output = [output]

console.log(output);

One way is to flat this 2D array first.

var output = {};
var flatArray = data.reduce(function(a, b) {
  return a.concat(b);
}, []);

flatArray.forEach(function(obj) {
  output[obj.year] = (output[obj.year] || 0) + obj.value;
});

output = [output]
console.log(output);

output: [{ 2015: 33000, 2016: 3000, 2017: 900 }]

You could use a hash table for collecting a single year and a nested approach for the arrays with iterating all properties of the given objects.

Then create new properties and add the actual value.

It works with an arbitrary count of properties.

 var data = [[{ year: 2015, value: 23000, value1: 1000 }, { year: 2016, value: 1000, value1: 2000 }, { year: 2017, value: 400, value1: 3000 }], [{ year: 2015, value: 10000, value1: 1000 }, { year: 2016, value: 2000, value1: 3000 }, { year: 2017, value: 500, value1: 2000 }]], result = data.reduce(function (hash) { return function (r, a) { a.forEach(function (o) { if (!hash[o.year]) { hash[o.year] = { year: o.year }; r.push(hash[o.year]); } Object.keys(o).forEach(function (k) { if (k !== 'year') { hash[o.year][k] = (hash[o.year][k] || 0) + o[k]; } }); }); return r; }; }(Object.create(null)), []); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Here's a working solution. This will do what you're looking for. Hope it helps!

 var arr = [ [{year:2015, value:23000, value1:1000},{year:2016,value:1000, value1:2000},{year:2017,value:400, value1:3000}], [{year:2015, value:10000, value1:1000},{year:2016,value:2000, value1:3000},{year:2017,value:500, value1:2000}], ] var result = []; for(var i = 0; i < arr[0].length; i++){ var count = 0 var count2 = 0; for(var j = 0; j < arr.length; j++){ var year = arr[j][i].year; count += arr[j][i].value; count2 += arr[j][i].value1; } result.push({ year: year, value: count, value1: count2 }); } console.log(result); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM