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}];
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 ()
.