Update javascript object with another object, but only existing keys

Viewed 3732

Is there a function, either in Javascript or Lodash, in which I can "update" one object with values from another object, but without adding new keys?

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }

Something like update(foo, bar), overwriting ("updating") any existing keys, but not adding non-existing keys:

{ 'a': 0, 'b': 2 }

There's almost certainly a similar question like this on StackOverflow, but I've not been able to find it.

6 Answers

Following are some of the ways you could achieve the desired result.

Instead of modifying the original objects, following code snippets create a new object with all the keys of the target object.

Using Nullish Coalescing Operator (??)

Nullish coalescing operator returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand. For more details on this operator, see Nullish coalescing operator (??)

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }

function update(target, src) {
  const res = {};
  Object.keys(target)
        .forEach(k => res[k] = (src[k] ?? target[k]));
  return res;
}

console.log(update(foo, bar));

Using hasOwnPropery() method

?? operator will fail for properties with null or undefined values. As an alternative, you could use hasOwnProperty() method. For details on this method, see Object.prototype.hasOwnProperty()

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }

function update(target, src) {
  const res = {};
  Object.keys(target)
        .forEach(k => res[k] = (src.hasOwnProperty(k) ? src[k] : target[k]));
  return res;
}

console.log(update(foo, bar));

Using 'in' operator

You could also use in operator to check for property existence in source object but keep in mind that in operator returns true if the specified property is in the specified object or its prototype chain. For details on in operator, see in operator

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }

function update(target, src) {
  const res = {};
  Object.keys(target)
        .forEach(k => res[k] = (k in src ? src[k] : target[k]));
  return res;
}

console.log(update(foo, bar));

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }

This could also be written slightly more concisely using lodash.

_.assign prefers the values in bar

_.assign({}, foo, _.pick(bar, _.keys(foo)))
{a: 0, b: 2}

_.defaults prefers the values in foo

_.defaults({}, foo, _.pick(bar, _.keys(foo)))
{a: 0, b: 1}

Or extending on from @Yousaf's answer, this could also be done in pure ES6 functional style as a one-liner without needing to create an intermediate object:

Object.fromEntries(Object.entries(foo)
  .map(([key, value]) => [
    key, 
    key in bar ? bar[key] : foo[key]
  ]) 
);

A simple easy and generic solution without using any library :

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }


function updateObject(firstObj, secondObj){

   Object.keys(firstObj).forEach(key => {
 if(secondObj.hasOwnProperty(key)){ 
    firstObj[key]=secondObj[key];    
   }})

  return firstObj;
}

console.log(updateObject(foo,bar));

This is a common pattern, and this is how I have been doing it. I think that it is very clear, but might be slower in some circumstances:

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }
Object.keys(foo).map(key => {
  if (key in bar) {
    foo[key] = bar[key]
  }
})

this should do it:

var foo = { 'a': 0, 'b': 1 }
var bar = { 'b': 2, 'c': 3 }
Object.entries(bar).forEach( ([key, val]) => { if(foo.hasOwnProperty(key)){ foo[key] = val } })

Just for fun, here it is with reduce:

let foo = { 'a': 0, 'b': 1 }
const bar = { 'b': 2, 'c': 3 }

foo = Object.keys(bar).reduce((foo, key) => {
  if(foo[key] != null){ foo[key] = bar[key]; }
  return foo;
}, foo);

console.log(foo);

(This assumes no value in foo is explicitly set to null or undefined, but allows for all other falsy values.)

Related