sum values in object if multiple keys are the same

2020-06-28 01:34发布

问题:

for example i have 5 objects:

{ row: aa, col: 1, value: 1 }
{ row: bb, col: 2, value: 1 }
{ row: bb, col: 3, value: 1 }
{ row: aa, col: 1, value: 1 }
{ row: aa, col: 2, value: 1 }

i want to sum values if row and col are the same, so the output should be:

{ row: aa, col: 1, value: 2 }
{ row: bb, col: 2, value: 1 }
{ row: bb, col: 3, value: 1 }
{ row: aa, col: 2, value: 1 }

thank you for your help!

tried this: Sum javascript object propertyA values with same object propertyB in array of objects

回答1:

You can do this with reduce() and one object to store keys.

var data = [
  { row: 'aa', col: 1, value: 1 },
  { row: 'bb', col: 2, value: 1 },
  { row: 'bb', col: 3, value: 1 },
  { row: 'aa', col: 1, value: 1 },
  { row: 'aa', col: 2, value: 1 }
]

var o = {}
var result = data.reduce(function(r, e) {
  var key = e.row + '|' + e.col;
  if (!o[key]) {
    o[key] = e;
    r.push(o[key]);
  } else {
    o[key].value += e.value;
  }
  return r;
}, []);

console.log(result)



回答2:

Just for completeness, with a version for variable keys, an object for grouping the parts and Array#forEach.

var data = [{ row: 'aa', col: 1, value: 1 }, { row: 'bb', col: 2, value: 1 }, { row: 'bb', col: 3, value: 1 }, { row: 'aa', col: 1, value: 1 }, { row: 'aa', col: 2, value: 1 }],
    grouped = [];

data.forEach(function (a) {
    var key = ['row', 'col'].map(function (k) { return a[k]; }).join('|');
    if (!this[key]) {
        this[key] = { row: a.row, col: a.col, value: 0 };
        grouped.push(this[key]);
    }
    this[key].value += a.value;
}, Object.create(null));

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }



回答3:

What I would do is put your objects in an array then iterate over that and check on each iteration if the key of a new object matches that of an old one and load the objects into a separate array if there isn't a match. If it does match then add its value to the value of the old own. I tested the following code and it seems to work how you want.

 var array = [{ row: 'aa', col: 1, value: 1 },
         { row: 'bb', col: 2, value: 1 },
         { row: 'bb', col: 3, value: 1 },
         { row: 'aa', col: 1, value: 1 },
         { row: 'aa', col: 2, value: 1 }];

 var newArray = [];

 for(var x in array) {
    for(var y in newArray) {
        var found = false;
        if(array[x].row == newArray[y].row && array[x].col == newArray[y].col) {
             newArray[y].value += array[x].value;
             found = true;
             break;
        }
    }
    if(!found) {
          newArray.push(array[x]);
    }
 }

 console.log(newArray);