George Edwards
George Edwards

Reputation: 9229

Aggregate records in JavaScript

Given an array of objects representing a series of transactions i.e.

[{ person: 'a', sweets: 5 }, { person: 'b', sweets: 8 }, { person: 'a', sweets: 6 }]

How can I efficiently consolidate these records, to a total tally for each person i.e. :

[{ person: 'a', sweets: '11'}, { person: 'b', sweets: 8 }]

Is there some inbuilt function I donlt know about, or would I have to prototype one?

Upvotes: 0

Views: 80

Answers (2)

Daniel Oliveira
Daniel Oliveira

Reputation: 1290

There isn´t any built in function. You have to use two loops. Firstly you need to loop through the original array and for each iteration of that loop you need to loop through the final array to find the correct position to update. I would do something like this (I did not test this solution):

var arrayStart = [{ person: 'a', sweets: 5 }, { person: 'b', sweets: 8 }, { person: 'a', sweets: 6 }]
var arraySum = [];

arrayStart.forEach(function(valueStart, indexStart){
  var found = false;
  for(var i = 0; i < arraySum.length; i++){
    if(arraySum[i].person == valueStart.person){
      found = true;
      arraySum[i].sweets += valueStart.sweets;
      break;
    }
  } 
  if(!found){
    arraySum.push(valueStart);
  }
});

console.log(arraySum);

You can also use @NinaScholz solution, using an Hash-table prevents the second loop, basically it is more efficient.

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386654

You could use a hash table for grouping and summing.

var data = [{ person: 'a', sweets: 5 }, { person: 'b', sweets: 8 }, { person: 'a', sweets: 6 }],
    grouped = [];

data.forEach(function (a) {
    if (!this[a.person]) {
        this[a.person] = { person: a.person, sweets: 0 };
        grouped.push(this[a.person]);
    }
    this[a.person].sweets += a.sweets;
}, Object.create(null));

console.log(grouped);

Upvotes: 2

Related Questions