Merge and Add values of objects in an array

Viewed 55

I am quite stuck on this. I have an array of objects. All of the objects have the same keys with different values. Like this

[{'fxiC6Y9ZyAM7BA35': 58, '1z5WcPsr97Szv4TM': 58, 'HDcNgheglFuoZ78d': 64, 'x7IkUjDjikXTpubn': 64, '7lnJSC07g1PoDycH': 128},
{'fxiC6Y9ZyAM7BA35': 74, '1z5WcPsr97Szv4TM': 74, 'HDcNgheglFuoZ78d': 82, 'x7IkUjDjikXTpubn': 82, '7lnJSC07g1PoDycH': 164},
{'fxiC6Y9ZyAM7BA35': 74, '1z5WcPsr97Szv4TM': 74, 'HDcNgheglFuoZ78d': 78, 'x7IkUjDjikXTpubn': 78, '7lnJSC07g1PoDycH': 156}]

I have access to Lodash but cannot find the best approach to merge and add the values of each key into one object.

{fxiC6Y9ZyAM7BA35: 206, 1z5WcPsr97Szv4TM: 206, HDcNgheglFuoZ78d: 224, x7IkUjDjikXTpubn: 224, 7lnJSC07g1PoDycH: 448}
3 Answers

You can just use Array.reduce()

const input = [{'fxiC6Y9ZyAM7BA35': 58, '1z5WcPsr97Szv4TM': 58, 'HDcNgheglFuoZ78d': 64, 'x7IkUjDjikXTpubn': 64, '7lnJSC07g1PoDycH': 128},
{'fxiC6Y9ZyAM7BA35': 74, '1z5WcPsr97Szv4TM': 74, 'HDcNgheglFuoZ78d': 82, 'x7IkUjDjikXTpubn': 82, '7lnJSC07g1PoDycH': 164},
{'fxiC6Y9ZyAM7BA35': 74, '1z5WcPsr97Szv4TM': 74, 'HDcNgheglFuoZ78d': 78, 'x7IkUjDjikXTpubn': 78, '7lnJSC07g1PoDycH': 156}
]

const output = input.reduce((acc, cur) => {
  Object.keys(cur).forEach(key => {
    if (!acc[key]) acc[key] = 0;
    acc[key] += cur[key];
  });
  return acc;
}, {});

console.log(output);

You could chaining these with lodash:

const res = _.chain(data)
  .flatMap(_.toPairs)
  .groupBy(_.head)
  .mapValues((pair) => _.reduce(pair, (sum, [_, val]) => sum + val, 0))
  .value();

Step by step:

  • flatten in to array of key-value pairs with _.flatMap
    [
      ["fxiC6Y9ZyAM7BA35", 58],
      ["1z5WcPsr97Szv4TM", 58],
      ["HDcNgheglFuoZ78d", 64],
      ["x7IkUjDjikXTpubn", 64],
      ["7lnJSC07g1PoDycH", 128],
      ["fxiC6Y9ZyAM7BA35", 74],
      ["1z5WcPsr97Szv4TM", 74],
      ["HDcNgheglFuoZ78d", 82],
      ["x7IkUjDjikXTpubn", 82],
      ["7lnJSC07g1PoDycH", 164],
      ["fxiC6Y9ZyAM7BA35", 74],
      ["1z5WcPsr97Szv4TM", 74],
      ["HDcNgheglFuoZ78d", 78],
      ["x7IkUjDjikXTpubn", 78],
      ["7lnJSC07g1PoDycH", 156],
    ]
    
  • group by key with _.groupBy
    {
      fxiC6Y9ZyAM7BA35: [
        [ 'fxiC6Y9ZyAM7BA35', 58 ],       
        [ 'fxiC6Y9ZyAM7BA35', 74 ],       
        [ 'fxiC6Y9ZyAM7BA35', 74 ]        
      ],
      '1z5WcPsr97Szv4TM': [
        [ '1z5WcPsr97Szv4TM', 58 ],       
        [ '1z5WcPsr97Szv4TM', 74 ],       
        [ '1z5WcPsr97Szv4TM', 74 ]        
      ],
      HDcNgheglFuoZ78d: [
        [ 'HDcNgheglFuoZ78d', 64 ],       
        [ 'HDcNgheglFuoZ78d', 82 ],       
        [ 'HDcNgheglFuoZ78d', 78 ]        
      ],
      x7IkUjDjikXTpubn: [
        [ 'x7IkUjDjikXTpubn', 64 ],       
        [ 'x7IkUjDjikXTpubn', 82 ],       
        [ 'x7IkUjDjikXTpubn', 78 ]        
      ],
      '7lnJSC07g1PoDycH': [
        [ '7lnJSC07g1PoDycH', 128 ],      
        [ '7lnJSC07g1PoDycH', 164 ],      
        [ '7lnJSC07g1PoDycH', 156 ]       
      ]
    }
    
  • map the values of each group and with each, calculate sum

Demo

const data = [
  {
    fxiC6Y9ZyAM7BA35: 58,
    "1z5WcPsr97Szv4TM": 58,
    HDcNgheglFuoZ78d: 64,
    x7IkUjDjikXTpubn: 64,
    "7lnJSC07g1PoDycH": 128,
  },
  {
    fxiC6Y9ZyAM7BA35: 74,
    "1z5WcPsr97Szv4TM": 74,
    HDcNgheglFuoZ78d: 82,
    x7IkUjDjikXTpubn: 82,
    "7lnJSC07g1PoDycH": 164,
  },
  {
    fxiC6Y9ZyAM7BA35: 74,
    "1z5WcPsr97Szv4TM": 74,
    HDcNgheglFuoZ78d: 78,
    x7IkUjDjikXTpubn: 78,
    "7lnJSC07g1PoDycH": 156,
  },
];

const res = _.chain(data)
  .flatMap(_.toPairs)
  .groupBy(_.head)
  .mapValues((pair) => _.reduce(pair, (sum, [_, val]) => sum + val, 0))
  .value();

console.log(res);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/lodash.min.js"></script>

Use lodash's _.mergeWith() and add the values of the merge properties:

const data = [{"fxiC6Y9ZyAM7BA35":58,"1z5WcPsr97Szv4TM":58,"HDcNgheglFuoZ78d":64,"x7IkUjDjikXTpubn":64,"7lnJSC07g1PoDycH":128},{"fxiC6Y9ZyAM7BA35":74,"1z5WcPsr97Szv4TM":74,"HDcNgheglFuoZ78d":82,"x7IkUjDjikXTpubn":82,"7lnJSC07g1PoDycH":164},{"fxiC6Y9ZyAM7BA35":74,"1z5WcPsr97Szv4TM":74,"HDcNgheglFuoZ78d":78,"x7IkUjDjikXTpubn":78,"7lnJSC07g1PoDycH":156}]

const result = _.mergeWith({}, ...data, (ov = 0, sv) => ov + sv)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

Related