Reputation: 4011
I have to deeply update an object with a provided one , keeping only the properties/paths found in the source object. I tried Lodash.merge, but it merges all the properties of the second object, I want to merge only the properties found in the source object.
Here is an example:
const ob1 = {
a1: {
b1: 2
},
a2: 5
}
const obj2 = {
a1: {
b1: 4,
b2: 9
},
a3: 6
}
expected result = {
a1: {
b1: 4
},
a2: 5
}
I'd like the simplest solution with es6 or lodash utils.
Any ideas? Thanks!
Upvotes: 0
Views: 183
Reputation: 66123
If you want a custom merge strategy, perhaps you can write your own recursive function. In the recursive function, you basically pass in your target and your source. Based on your question, the target will be obj1
and the source will be obj2
.
Your logic is that:
obj1
does not contain a key that is in obj2
, we keep the key-value pair from the obj1
, the sourceobj1
contains a key that is obj2
, then:
obj2
value to override obj1
valueSee proof-of-concept below:
const obj1 = {
a1: {
b1: 2
},
a2: 5
}
const obj2 = {
a1: {
b1: 4,
b2: 9
},
a3: 6
}
function smartMerge(target, source) {
const o = {};
// Iterate throught all keys in your target
for(let k in target) {
// If a matching key is found in source
if (k in source) {
// If they are both objects, then we run recurisve merge logic
if (typeof target[k] === 'object' && typeof source[k] === 'object') {
o[k] = smartMerge(target[k], source[k]);
}
// Otherwise, we let the source override the value
else {
o[k] = source[k];
}
}
// If no matching key is found, we keep the target value
else {
o[k] = target[k];
}
}
return o;
}
const result = smartMerge(obj1, obj2);
/* Expected:
{
a1: {
b1: 4
},
a2: 5
}
*/
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Upvotes: 1