Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

Consider an array that contains objects. Each object of the array is composed of both label and value attributes. I want to be able to compare each object of the array, and if the labels are the same, sum their values so as the labels do not repeat and have the sum of all previous values.

Like, for instance, if the array was this:

[{
  label: "A",
  value: 10
  }, {
  label: "B",
  value: 20
  }, {
  label: "C",
  value: 30
  }, {
  label: "C",
  value: 40
  }, {
  label: "D",
  value: 12
  }, {
  label: "D",
  value: 23
}]

In the end I would have the array with only four labels (A, B, C, D) and the value 10 for A, 20 for B, 70 for C and 35 for D.

I tried using a for loop:

for (i = 1; i < transformation.length; i++) {
              if (transformation[i-1].label == transformation[i].label) {
                result.label.push = transformation[i].label;
                result.value.push = transformation[i-1].value + transformation[i].value;

              }
            };

But I got stuck here and have no ideas on how to deal with non repeated values. I need the final array to still be an array, not an object.

share|improve this question

This is a perfect case for Array.reduce!

var sums = arr.reduce(function(results, item) {
    if (!results.hasOwnProperty(item.label)) {
        results[item.label] = 0;
    }

    results[item.label] += item.value;
    return results;
}, {});

console.log(sums); //Object {A: 10, B: 20, C: 70, D: 35}

results will contain 4 keys A,B,C,D, each containing the total of times it occurred in the array.

share|improve this answer
    
A subsequent Object.entries(sums).map(a => ({label: a[0], value: a[1]})); would create an array with object like {label: "X", value: y}. – Xufox Jul 6 at 23:54
    
@tymeJV This does not fully work since I can't use the .map function on the result and I do need it. It returns an object instead of returning an array. – Shoplifter.Doe Jul 7 at 1:16
    
@Xufox my console says Object.entries is not a function – Shoplifter.Doe Jul 7 at 1:20
    
@Shoplifter.Doe Well, look at the browser compatibility of that function. It’s supported almost nowhere. But still, it would solve your problem. – Xufox Jul 7 at 1:24
    
@Xufox Yes it would. I remember now I tried to use it some time ago. Isn't there another way to get the result as an array instead of an object? – Shoplifter.Doe Jul 7 at 1:26

You can just use Array.reduce

Same as @tymeJV, but as a one-liner

var sum = transformation.reduce(function(sumAll, item) {
  sumAll[item.label] = item.value + sumAll[item.label] || 0;
  return sumAll;
}, {})

console.log(sum) // {"A":10,"B":20,"C":70,"D":35}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.