1

I have this multidimensional array and I need to merge the fields that are equal and sum the sum values

var data = [
      [
        {field: 123, sum: 100},
        {field: 345, sum: 98}
      ],[
        {field: 123, sum: 12},
        {field: 345, sum: 20}
      ]
    ];

So from this array I need a new one like this.

var newArray = [
   {field: 123, sum: 112},
   {field: 345, sum: 118}
];

and here is my code.

var newArray = [];
for(var i = 0; i < data.length; i++) {
  for(var j = 0; j < data[i].length; j++) {
    var matched = false;
    for(var c = 0; c < newArray.length; c++) {
      if(data[i][j].field == newArray[c].field) {
        matched = true;
        newArray[c].sum + data[i][j].sum;
      }
    }
    console.log(data[i][j]);
    if(!matched) {
      newArray.push(data[i][j]);
    }
  }
}

but I don't get the values right. console.log(newArray);

3
  • 2
    Can you show us where you are stuck? Commented Jun 5, 2015 at 12:59
  • Your problem is in newArray[c].sum + data[i][j].sum; you need += to add, not just +. Using just the + operator performs the operation, but it is not saved anywhere. Commented Jun 5, 2015 at 13:12
  • my bad! I have put my code and what I was missing was a = sign on this line "newArray[c].sum + data[i][j].sum;" :( Commented Jun 5, 2015 at 13:17

4 Answers 4

2

In functional programming, this would be a classic map-reduce problem, or more specifically a reduce-by-key.

If you are working with underscore, you could do something like this:

var op = _.chain(data)
 //first put it all in one array
 .flatten()
 //then group by the field
 .groupBy(function(item){return item.field;})
 //then sum up all of the "sum" properties
 .mapObject(function(val,key){
    return _.reduce(val, function(total,sum){
        return total + sum.sum;
    },0);
 })
 //then map it back into our original data structure
 .pairs()
 .map(function(item){
    return {field: item[0], sum: item[1]};
 });
Sign up to request clarification or add additional context in comments.

Comments

1

ECMAScript6 solution (if available):

data
    .reduce((a, b) => a.concat(b))
    .reduce((a, b) => {
        var idx = a.findIndex(elem => elem.field == b.field);
        if (~idx) {
            a[idx].sum += b.sum;
        }
        else {
            a.push(JSON.parse(JSON.stringify(b)));
        }
        return a;
    }, []);

Your issue is just a typo, though:

- newArray[c].sum + data[i][j].sum
+ newArray[c].sum += data[i][j].sum

Comments

0

Your problem is in the line

newArray[c].sum + data[i][j].sum;

This line performs the calculation, but it is not stored in newArray. If you change the operator to += your function will work correctly.

newArray[c].sum + data[i][j].sum; // Sums the two values
newArray[c].sum += data[i][j].sum; // Sums and saves them to newArray[c].sum

A correct solution is shown here in this jsFiddle.

var newArray = [];
for(var i = 0; i < data.length; i++){
    var objects = data[i];
    for(var n = 0; n < objects.length; n++){
        var existed = false;
        for(var z = 0; z < newArray.length; z++){
            if(newArray[z].field === objects[n].field){
                newArray[z].sum += objects[n].sum;
                existed = true;
            }
        }
        if(!existed){
            newArray.push({field : objects[n].field, sum: objects[n].sum});                
        }
    }
}

You cycle through all the elements, and then sum them in a new array called newArray. It looks if an object with the field already exists, and if it does, adds the sum to the existing element. If not, it creates a new element with the field value and the initial sum.

2 Comments

Good answer .. but try to wait till one updates code and then answer .. :) Or else it encourages people to upload question without even taking any effort..
Thanks for your response @Robin and sorry for not provide my code. I was missing a "=" on my code.
0

just have a look at this code

 <script>
   var data = [
      [
        {field: 123, sum: 100},
        {field: 345, sum: 98}
      ],[
        {field: 123, sum: 12},
        {field: 345, sum: 20}
      ]
    ];


var o=[];
var j=0;


while(j<data.length)
{
    var obj1={};
    var field; sum=0;
    for(i=0; i<data.length; i++)
    {
      field=data[i][j].field;
      sum=sum+data[i][j].sum;
    }
    obj1.field=field;
    obj1.sum=sum;
    o.push(obj1);
    j++;
}

console.log(o)

    </script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.