Add values โ€‹โ€‹of matching keys in an array of objects

I have an array with a number of objects with the corresponding keys:

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

I want to iterate over the array and, if the keys match, I want to add the results of each of them and return one object with the sum of each key.

i.e.

 {a: 6, b: 9, c: 6, d: 3} 

In my code there is

 function combine() { var answer = []; for(var i in arguments){ answer.push(arguments[i]) } answer.reduce(function(o) { for (var p in o) answer[p] = (p in answer ? answer[p] : 0) + o[p]; return answer; }, {}); } 

I can find the answer here if I had to use the underscore library, however I want to do this without using the library. I think I hardly understand how the reduce method works - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Any help regarding how to solve this problem would be greatly appreciated. Also, I believe this is an answer that should be somewhere in SO without having to use a library.

Thanks in advance.

+5
source share
6 answers

Scroll through each object and add it.

  var a = [{a: 2, b: 5, c: 6}, {a:3, b: 4, d:1},{a: 1, d: 2}]; var ans = {}; for(var i = 0; i < a.length; ++i){ for(var obj in a[i]){ ans[obj] = ans[obj] ? ans[obj] + a[i][obj] : a[i][obj]; } } document.write(JSON.stringify(ans)); 

 ans[obj] = ans[obj] ? ans[obj] + a[i][obj] : a[i][obj]; This line is the same as // check if the object already exists(or not falsy) in answer, if Yes add that value to the new value if(ans[obj]) { ans[obj] = ans[obj] + a[i][obj]; } // else create a new object in the answer and set it to the value from the array else { ans[obj] = a[i][obj]; } 
+1
source

Using Array.reduce () and Array.map ()

 var tab = [{a: 2, b: 5, c: 6}, {a:3, b: 4, d:1},{a: 1, d: 2}]; function sum(tab) { return tab.reduce((a, b) => { Object.keys(b).map(c => a[c] = (a[c] || 0) + b[c]); return a; }); } console.log(sum(tab)); 
+2
source

try it

 resobj = {}; [{a: 2,b: 5,c: 6}, {a: 3,b: 4,d: 1}, {a: 1,d: 2}].forEach(function(v) { var keys = Object.keys(v); for (i = 0; i < keys.length; i++) { if (typeof resobj[keys[i]] == 'undefined') { resobj[keys[i]] = Number(v[keys[i]]); } else { resobj[keys[i]] += v[keys[i]]; } } }) document.write(JSON.stringify(resobj)) 
+1
source

The callback function in reduce() requires two arguments:

  • The result returned for the previous value (or the initial value, if the first)
  • Current value in the loop

You should also pass an empty object as a second parameter to reduce. This is the one you fill out.

 var input = [ {a: 2, b: 5, c: 6}, {a: 3, b: 4, d: 1}, {a: 1, d: 2} ]; var answer = input.reduce(function(prev, curr) { for (var p in curr) { prev[p] = (prev[p] || 0) + curr[p]; } return prev; // this will be passed as prev in the next iteration or returned as the result. }, {}); // The {} is the initial value passed as prev console.log(answer); 
+1
source

Another solution with a decrease:

 var result = [{a: 2, b: 5, c: 6}, {a:3, b: 4, d:1},{a: 1, d: 2}].reduce(function(prev, current) { Object.keys(current).forEach(function(key) { prev[key] = (prev[key] || 0) + current[key]; }); return prev; }, {}); document.write('<pre>' + JSON.stringify(result, 0, 2) + '</pre>'); 
0
source

Just use Array#forEach() and the object for the result.

 var data = [{ a: 2, b: 5, c: 6 }, { a: 3, b: 4, d: 1 }, { a: 1, d: 2 }], obj = {}; data.forEach(function (o) { Object.keys(o).forEach(function (k) { obj[k] = (obj[k] || 0) + o[k]; }); }) document.write('<pre>' + JSON.stringify(obj, 0, 4) + '</pre>'); 
0
source

Source: https://habr.com/ru/post/1244205/


All Articles