djechlin
djechlin

Reputation: 60788

Reducing an array of rows to an aggregate summed-up row using Underscore or Lodash

I have an array of rows that looks like this:

[
  { 
    metric1: 50,
    metric2: 60
  },
  {
    metric1: 100,
    metric2: 120;
  }
]

and I'd like to reduce this to a single row that looks like this:

{
  metric1: 150,
  metric2: 180
}

So far I have a pretty longhand approach:

_.reduce(function(row, aggregate) {
  _.each(row, function(value, metric) {
    aggregate[metric] = aggregate[metric] || 0;
    aggregate[metric] += value;
  });
  return aggregate;
}, {});

But really feel this can be done much cleaner with Underscore or Lodash functional programming. Any ideas?

Upvotes: 0

Views: 2771

Answers (1)

SimpleJ
SimpleJ

Reputation: 14768

You could do it cleanly with vanilla javascript:

var result = data.reduce(function(totals, v) {
    totals.metric1 += v.metric1;
    totals.metric2 += v.metric2;
    return totals;
}, {metric1: 0, metric2: 0});

Edit: If the metric names aren't known until runtime, your solution works fine. Here is another solution using _.merge:

var result = _.merge.apply(null, [{}].concat(data).concat(function(total, v) {
  return (total || 0) + v;
}));

Or if you're using ES6:

var result = _.merge({}, ...data, (total=0, v) => {
  return total + v;
});

Upvotes: 3

Related Questions