Home > Back-end >  Copy values from nested object to another
Copy values from nested object to another

Time:09-02

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.

CodePudding user response:

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)

CodePudding user response:

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

CodePudding user response:

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,
  }
}
*/

  • Related