Copy values from nested object to another

41 Views Asked by At

I have a two nested objects that I want to compare with each other.

obj1 is the new structure that I need.

obj2 is the old structure that I'm comparing with and has the values I need.

Basically what I'm trying to achieve here is the following:

If a key from obj1 exists in obj2 take the value.

for example:

let obj1 = {
 a: 10,
 c: {
   d: 30,
   e: 50,
 },
};

let obj2 = {
 a: 100,
 x: 200,
 c: {
   e: 300,
   y: 400,
 },
};

should result in

result = {
 a: 100,
 c: {
  d: 30,
  e: 300,
 }
}

I'm having a hard time setting up a recursive function for this problem.

I've read the documentation on lodash library, but there is not function thats specificly solves this problem.

3

There are 3 best solutions below

0
Michele Viviani On BEST ANSWER

You can use the reduce method, over Obj1 keys. Check if the key is in Obj2 then add new property to the carry value of the reducer. Initialized with {}

const obj1 = {
  a: 10,
  c: {
    d: 30,
    e: 50,
  }
};

const obj2 = {
  a: 100,
  x: 200,
  c: {
    e: 300,
    y: 400,
  }
};

const hasProp = Object.prototype.hasOwnProperty
const newObj = Object.keys(obj1).reduce((obj, currentKey) => {
    obj[currentKey] = hasProp.call(obj2, currentKey) ? obj2[currentKey] : obj1[currentKey];
    return obj;
}, {})

console.log(newObj)

0
Sakil On

let obj1 = {
    a: 10,
    c: {
        d: 30,
        e: 50,
    },
};

let obj2 = {
    a: 100,
    x: 200,
    c: {
        e: 300,
        y: 400,
    },
};

function modifyObj(acc = {}, elem = [], obj = {}) {
    let key = elem[0];
    let value = elem[1];
    if (typeof value != 'object') {
        acc[key] = (obj[key] || value); //set value "obj[key]" if not present set it's current value
    } else {
        //recursively call 'modifyObj' if value is object
        acc[key] = Object.entries(value).reduce((acc2, elem2) => modifyObj(acc2, elem2, obj[key]), {});
    }
    return acc;
}

let output = Object.entries(obj1).reduce((acc, elem) => modifyObj(acc, elem, obj2), {});
console.log(output);

//Way 2
//let output2 = modifyObj({}, ['main', obj1], {main: obj2}).main;
//console.log(output2);

0
majusebetter On

const obj1 = {
  a: 10,
  c: {
    d: 30,
    e: 50,
  }
};

const obj2 = {
  a: 100,
  x: 200,
  c: {
    e: 300,
    y: 400,
  }
};


function updateRecursive(obj1, obj2, result) {

  // Iterate over all keys in obj1
  for (const key of Object.keys(obj1)) {
    // If the field also exists in obj2
    if (obj2[key]) {
      // Is it an object type?
      if (typeof obj2[key] === 'object') {
        // Update sub object
        updateRecursive(obj1[key], obj2[key], result[key]);
      }
      // Else, if primitive type (including null and undefined)
      else {
        result[key] = obj2[key];
      }
    }
  }
}


function update(obj1, obj2) {
  // Copy obj1, since this is the base
  const result = JSON.parse(JSON.stringify(obj1));
  // Update object recursively
  updateRecursive(obj1, obj2, result);
  return result;
}

console.log(JSON.stringify(update(obj1, obj2), null, 2));

/* Output:
{
  a: 100,
  c: {
    d: 30,
    e: 300,
  }
}
*/