Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use mergeWith of Lodash with nested objects

I have two objects like that:

const object1 = {first: [{a: 0, b:3}], second: [{a: 1, b:2}], third: [{a: 3, b:2}]}
const object2 = {first: [{a: 1, b:0}], second: [{a: 10, b:0}], third: [{a: 2, b:3}]}

and I want the sum of these two objects:

const res = {first: [{a: 1, b:3}], second: [{a: 11, b:2}], third: [{a: 5, b:5}]}

I tried to use mergeWith of Lodash in this way:

const res = mergeWith({}, object1, object2, add)

but I get:

{first: NaN, second: NaN, third: NaN}

How can I use mergeWith with nested objects?


1 Answers

When doing mergeWith you need to pass a customizer. Lodash then does a recursive merging of values.

The trick is that if your customizer returns undefined, then merge is used to combine the values. However, since add returns NaN for incompatible values, that value is used instead - so if you merely have a function that works like add but returns undefined instead of NaN, then mergeWith will do all the heavy lifting for you:

const object1 = {first: [{a: 0, b:3}], second: [{a: 1, b:2}], third: [{a: 3, b:2}]}
const object2 = {first: [{a: 1, b:0}], second: [{a: 10, b:0}], third: [{a: 2, b:3}]}

const res = _.mergeWith({}, object1, object2, customizer)

console.log(res);

function customizer(a, b) {
  // you can still use add
  const result = _.add(a, b);
  
  // ignore NaN values and return undefined instead
  if (_.isNaN(result)) { 
    return;
  }
  
  //only combine values that can be combined
  return result;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

An alternative shorter way to express this is by using defaultTo

const object1 = {first: [{a: 0, b:3}], second: [{a: 1, b:2}], third: [{a: 3, b:2}]}
const object2 = {first: [{a: 1, b:0}], second: [{a: 10, b:0}], third: [{a: 2, b:3}]}

const customizer = (a, b) => _.defaultTo(_.add(a, b), undefined)

const res = _.mergeWith({}, object1, object2, customizer)

console.log(res);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
like image 131
VLAZ Avatar answered Dec 10 '25 01:12

VLAZ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!