onegun
onegun

Reputation: 803

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

Upvotes: 0

Views: 1158

Answers (4)

Nina Scholz
Nina Scholz

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

HenryDev
HenryDev

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

RomanPerekhrest
RomanPerekhrest

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

Zohaib Ijaz
Zohaib Ijaz

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

Related Questions