Yes, there's a plethora of questions with titles similar to this and I can assure you I've tested almost all of them. Everything Google threw at me, I tried. None sufficed.
Considering these two objects:
const o1 = {
"someProperty": "someValue",
"anotherProperty": {
"p1": "v1",
"p2": "v2"
}
}
const o2 = {
"anotherProperty": {
"p1": "v1",
"p2": "v2"
}
}
How do I find the differences between o2
and o1
, by top-level keys, I believe, without "destroy" the object by setting properties' values as undefined
(honestly, I found that answer, here, preposterous).
Why do I need this? The here depicted o1
contains "all data" and o2
a subset that will be removed so I can perform an update. You can think of if as the inverse of an intersection.
In pseudo-code above, all I want as output is:
const diff = {
"someProperty": "someValue"
}
Of course, this is an oversimplified example, in the real deal I have many other properties, with different values, always of primitive data-tyes (plain text, integers, booleans...) one-level nested (like o2
) or deep down more levels, but always primitive types.
Sounds like a very simple thing but I just couldn't find anything without NodeJS, Lodash, Underscore or whatever other 3rd-party library.
CodePudding user response:
You could get the entries and check against. For objects perform the same and check if the result has some keys.
const
getDifference = (a, b) => Object.fromEntries(Object
.entries(a)
.reduce((r, [k, v]) => {
if (v && typeof v === 'object') {
let temp = getDifference(v, b[k] || {});
if (Object.keys(temp).length) r.push([k, temp]);
} else {
if (v !== b[k]) r.push([k, v]);
}
return r;
}, [])
),
o1 = { someProperty: "someValue", anotherProperty: { p1: "v1", p2: "v2", p3: 'v3' }, n1: { n2: { n3: 42 } } },
o2 = { someProperty: "someValue", anotherProperty: { p1: "v1", p2: "v2" } },
o3 = { anotherProperty: { p1: "v1", p2: "v2" } };
console.log(getDifference(o1, o3));
console.log(getDifference(o2, o3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>