Javascript’s Object.assign is shadow merge, loadsh’s _.merge is deep merge, but has probem for array.
const person = { name: { first: "Joe" }, age: 23, color: "green", pets: ["dog", "lizard"] }; const update = { name: { last: "Smith" }, color: "blue", book: "Harry Potter", pets: ["cat"] };
const merged1 = { ...person, ...update, name: { ...person.name, ...update.name }, pets: [...person.pets, ...update.pets] }; /*Object {name: Object, age: 23, color: "blue", pets: Array[3], book: "Harry Potter"} name: Object age: 23 color: "blue" pets: Array[3] 0: "dog" 1: "lizard" 2: "cat" book: "Harry Potter" */ const merged2 = _.merge({}, person, update); /* name: Object first: "Joe" last: "Smith" age: 23 color: "blue" pets: Array[2] 0: "cat" 1: "lizard" book: "Harry Potter" */
We can use Ramda.js to easy solve the problem:
console.log(R.mergeDeepWith(R.concat, person, update)); /* Object {name: Object, age: 23, color: "blue", pets: Array[2], book: "Harry Potter"} name: Object first: "Joe" last: "Smith" age: 23 color: "blue" pets: Array[2] 0: "cat" 1: "lizard" book: "Harry Potter" */
To make it more point-free style and more reuseable, we can do:
const _merge = R.mergeDeepWith(R.concat); console.log(_merge(person, update));