Reputation: 803
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
Upvotes: 0
Views: 1158
Reputation: 386578
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; }
Upvotes: 1
Reputation: 4953
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);
Upvotes: 0
Reputation: 92854
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);
Upvotes: 2
Reputation: 22885
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 }]
Upvotes: 1