Javascript multidimensional array, add, and de-duplicate!

var arr =[{a:1,b:2,c:2},{a:1,b:2,c:3},{a:2,b:3,c:2},{a:2,b:3,c:2},{a:1,b:4,c:2}];

arr is a multi-dimensional array with multiple attributes abcde in each array. For example, I only wrote abc3 attributes,
I want to implement traversing the array, when the values of an and b attributes are the same (only an and b), are required, then add their c,
finally implement the array is

arr2 =[{a:1,b:2,c:5},{a:2,b:3,c:4},{a:1,b:4,c:2}];
Apr.23,2021

var arr =[{a:1,b:2,c:2},{a:1,b:2,c:3},{a:2,b:3,c:2},{a:2,b:3,c:2},{a:1,b:4,c:2}];

var SEPERATOR = '_'

function groupBy(arr, cb){
  var group = {}
  
  arr.forEach(function(e){
    var k = cb && cb(e)
    if(Object.prototype.toString.call(k) == '[object String]') {
      if(!group[k]) group[k] = [e]
      else group[k].push(e)
    }
  })
  
  return group
}

var data = groupBy(arr, function(e){
  return e.a + SEPERATOR + e.b
})

var results = []

for(k in data) {
  if(data.hasOwnProperty(k)) {
    var keys = k.split(SEPERATOR)
    var a = parseInt(keys[0])
    var b = parseInt(keys[1])
    var c = data[k].reduce(function(a, e){ return a + e.c}, 0)
    results.push({a: a, b: b, c: c})
  }
}

console.log(results)

if there is a mistake, please correct it, and the god will spray it gently

< hr >

Update a few points:

  • the groupBy here is only for grouping. If you use a tool library such as underscore, lodash or ramda, you can find the corresponding method
  • .
  • in addition, I see that the subject has edited the question and added additional conditions to remove duplicates, which is also easy to achieve, because he said that I will not change the original answer without specifying the de-duplicating criteria. I just need to add some specific deduplicated logic to the transformed data
  • .
  • I probably took a look at the other two answers, and the idea is also quite good, using reduce to merge while iterating

var arr = [{a: 1, b: 2, c: 2}, {a: 1, b: 2, c: 3}, {a: 2, b: 3, c: 2}, {a: 2, b: 3, c: 2}, {a: 1, b: 4, c: 2}];

//
const attrs = ['a', 'b'];

const result = arr.reduce((list, o) => {
  const item = list.find(n => !attrs.find(attr => o[attr] !== n[attr]));
  !item ? list.push({...o}) : item.c += o.c;
  return list;
}, []);

console.log(result)

The problem of

is essentially a problem of grouping summation (SUM and GROUP BY) in SQL sentences. Since this is the case, you might as well use a cow knife to kill a chicken:

npm install --save alasql

then:

var alasql = require('alasql');
var arr =[{a:1,b:2,c:2},{a:1,b:2,c:3},{a:2,b:3,c:2},{a:2,b:3,c:2},{a:1,b:4,c:2}];
var res = alasql('SELECT a, b, SUM(c) AS c FROM ? GROUP BY a, b', [arr]);
console.log(res);

result:

[ { a: 1, b: 2, c: 5 },
  { a: 2, b: 3, c: 4 },
  { a: 1, b: 4, c: 2 } ]

attrs.find () of
  @ asseek  can be changed to  attrs.every ()  

.
Menu