3

This code merges two objects. How to amend it so that a property is discarded of the first object if it exists in the second object?

E.g. object 1 has this property:

surname: {
    test: '123',
    other: '124'
},

and object 2:

surname: {
    test: '124'
},

The merge would use the property of object 2 (other: '124' would not exist in the merged result)

function merge(...objects) {
    function m(t, s) {
        Object.entries(s).forEach(([k, v]) => {
            t[k] = v && typeof v === 'object' ? m(t[k] || {}, v) : v;
        });
        return t;
    }

    return objects.reduce(m, {});
}

var obj1 = {
        name: '112',
        surname: {
            test: '123',
            other: '124'
        },
        age: 151,
        height: '183',
        weight: 80
    },
    
    obj2 = {
        name: '114',
        surname: {
            test: '124'
        },
        age: 151,
        height: 184,
        weight: 81
    },
    
    result = merge(obj1, obj2);

console.log(result);
VLAZ
  • 26,331
  • 9
  • 49
  • 67
smolo
  • 737
  • 1
  • 15
  • 27
  • 1
    did you check this link https://stackoverflow.com/questions/50176456/merging-two-javascript-objects-into-one? The function should have a deep merge or a simple merge of two objects? – Kordrad Jun 14 '22 at 06:07
  • 1
    Thanks, $.extend(obj1, obj2) is what I had been looking for! The merge performed by $.extend() is not recursive by default; if a property of the first object is itself an object or array, it will be completely overwritten by a property with the same key in the second or subsequent object. The values are not merged. – smolo Jun 14 '22 at 06:18

2 Answers2

5
const a = { x:1, y:2}
const b = { x:5 }
const c = { ...a, ...b }
console.log(c)
// Answer will be {x: 5, y: 2}
1

You seem to want to do a shallow merge but with recreated objects to avoid references to the original ones.

A quick way for this is to use Object.assign for the merge, and then do a json stringify/parse (with the limitations of what JSON supports) to clone the result and lose the references (you could alternatively use structuredCloned if your environment/browser supports it).

So something like

function merge(...objects) {
  const shallowClone = Object.assign({}, ...objects);
  const asString = JSON.stringify(shallowClone);
  const asObject = JSON.parse(asString);
  return asObject;
}
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • It seems to works as intended. However, it is hard to tell what the difference is to monirshimul's solution, which seems simpler to me – smolo Jun 14 '22 at 08:58
  • @smolo that answer has only the shallow merge part. So it is keeping the original object references. If you do, *after the merge*, `obj2.surname.test = "new"` it will affect the `result` vairable as well. – Gabriele Petrioli Jun 14 '22 at 10:19