Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(_.merge in ES6/ES7)Object.assign without overriding undefined values

Tags:

There is _.merge functionality in lodash. I want to achieve the same thing in ES6 or ES7.

Having this snippet:

Object.assign({}, {key: 2}, {key: undefined}) 

I want to receive {key: 2}. Currently I receive {key: undefined}

This is NOT a deep merge.

Is it possible? If yes then how to achieve that?

like image 237
Filip Bartuzi Avatar asked Oct 11 '16 12:10

Filip Bartuzi


People also ask

Does object assign deep merge?

This is because Object. assign does a shallow merge and not a deep merge. A shallow merge means it will merge properties only at the first level and not the nested level.

How do I merge objects in ES6?

The easiest way to merge two objects in JavaScript is with the ES6 spread syntax / operator ( ... ). All you have to do is insert one object into another object along with the spread syntax and any object you use the spread syntax on will be merged into the parent object.

How do I merge objects in Lodash?

Lodash helps in working with arrays, strings, objects, numbers, etc. The _. merge() method is used to merge two or more objects starting with the left-most to the right-most to create a parent mapping object. When two keys are the same, the generated object will have value for the rightmost key.

Does Lodash merge deep copy?

The first detail is that merge() copies objects recursively, so _. merge() is a deep copy whereas _. assign() is a shallow copy. The second detail is how merge() handles undefined .


2 Answers

You can't achieve that with a straight usage of Object.assign, because each next object will rewrite the same keys for prev merge. The only way, to filter your incoming objects with some hand-crafted function.

function filterObject(obj) {     const ret = {};     Object.keys(obj)         .filter((key) => obj[key] !== undefined)         .forEach((key) => ret[key] = obj[key]);     return ret; } 
like image 76
steppefox Avatar answered Sep 27 '22 20:09

steppefox


You can simply filter out the keys with undefined values before passing them to Object.assign():

const assign = (target, ...sources) =>    Object.assign(target, ...sources.map(x =>      Object.entries(x)        .filter(([key, value]) => value !== undefined)        .reduce((obj, [key, value]) => (obj[key] = value, obj), {})    ))    console.log(assign({}, {key: 2}, {key: undefined}))
like image 21
Michał Perłakowski Avatar answered Sep 27 '22 21:09

Michał Perłakowski