[Javascript] Deep merge in Javascript with Ramda.js mergeDeepWith

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));

 

posted @ 2019-01-18 21:04  Zhentiw  阅读(418)  评论(0编辑  收藏  举报