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?
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With