Compare nested objects in JavaScript and return keys equality
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have two nested objects obj1
and obj2
and I want to compare them and the recursively return an object that for each nested key has a equality-like boolean flag
So for a given obj1
like
obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
}
}
and the obj2
like
obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new"
}
it should return
equality = {
prop1: false,
prop2: true,
prop3 : {
prop4: true,
prop5: false
},
prop6: false
}
If an object has a new property, like obj2.prop6
, then the equality will be equality.prop6 = false
.
For non-nested object a simple keys comparison solutions is here Get the property of the difference between two objects in javascript
While to recursively compare nested objects it is showed here JavaScript: Deep comparison recursively: Objects and properties
javascript
add a comment |
I have two nested objects obj1
and obj2
and I want to compare them and the recursively return an object that for each nested key has a equality-like boolean flag
So for a given obj1
like
obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
}
}
and the obj2
like
obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new"
}
it should return
equality = {
prop1: false,
prop2: true,
prop3 : {
prop4: true,
prop5: false
},
prop6: false
}
If an object has a new property, like obj2.prop6
, then the equality will be equality.prop6 = false
.
For non-nested object a simple keys comparison solutions is here Get the property of the difference between two objects in javascript
While to recursively compare nested objects it is showed here JavaScript: Deep comparison recursively: Objects and properties
javascript
1
Will both objects always have exact match properties?
– holydragon
14 hours ago
good point. Nope, so the equality could have a new key set tofalse
. Updating with this point. Thank you.
– loretoparisi
14 hours ago
add a comment |
I have two nested objects obj1
and obj2
and I want to compare them and the recursively return an object that for each nested key has a equality-like boolean flag
So for a given obj1
like
obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
}
}
and the obj2
like
obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new"
}
it should return
equality = {
prop1: false,
prop2: true,
prop3 : {
prop4: true,
prop5: false
},
prop6: false
}
If an object has a new property, like obj2.prop6
, then the equality will be equality.prop6 = false
.
For non-nested object a simple keys comparison solutions is here Get the property of the difference between two objects in javascript
While to recursively compare nested objects it is showed here JavaScript: Deep comparison recursively: Objects and properties
javascript
I have two nested objects obj1
and obj2
and I want to compare them and the recursively return an object that for each nested key has a equality-like boolean flag
So for a given obj1
like
obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
}
}
and the obj2
like
obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new"
}
it should return
equality = {
prop1: false,
prop2: true,
prop3 : {
prop4: true,
prop5: false
},
prop6: false
}
If an object has a new property, like obj2.prop6
, then the equality will be equality.prop6 = false
.
For non-nested object a simple keys comparison solutions is here Get the property of the difference between two objects in javascript
While to recursively compare nested objects it is showed here JavaScript: Deep comparison recursively: Objects and properties
javascript
javascript
edited 14 hours ago
loretoparisi
asked 14 hours ago
loretoparisiloretoparisi
8,07154973
8,07154973
1
Will both objects always have exact match properties?
– holydragon
14 hours ago
good point. Nope, so the equality could have a new key set tofalse
. Updating with this point. Thank you.
– loretoparisi
14 hours ago
add a comment |
1
Will both objects always have exact match properties?
– holydragon
14 hours ago
good point. Nope, so the equality could have a new key set tofalse
. Updating with this point. Thank you.
– loretoparisi
14 hours ago
1
1
Will both objects always have exact match properties?
– holydragon
14 hours ago
Will both objects always have exact match properties?
– holydragon
14 hours ago
good point. Nope, so the equality could have a new key set to
false
. Updating with this point. Thank you.– loretoparisi
14 hours ago
good point. Nope, so the equality could have a new key set to
false
. Updating with this point. Thank you.– loretoparisi
14 hours ago
add a comment |
4 Answers
4
active
oldest
votes
You could use reduce
to build new object and another get
method to get nested props from other object by string
and compare it to current prop value in first object.
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
To compare all properties of both objects you could create extra function that will perform loop by both objects.
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
1
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like{}
, it does not make the comparison.
– loretoparisi
13 hours ago
1
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
Ok, now it handles a nested lonelyprop11={}
object, but if you have like the sameprop12={}
in both, you will get the{}
as result for theprop12
keyword, instead ofbool
. See here jsfiddle.net/gpu20nwy
– loretoparisi
12 hours ago
1
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
|
show 1 more comment
You could iterate all keys and check the nested objects if both values are objects.
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
Thanks! This solution works in every condition even if the property is a void object likeprop7 = {}
. Maybe avoiding the ECMA6Spread
notation for more compatibility could help.
– loretoparisi
13 hours ago
1
without spread notSet
.
– Nina Scholz
13 hours ago
maybe likeObject.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
1
w h a t e v e r ...
– Nina Scholz
13 hours ago
add a comment |
Loop through each key and compare the properties. If the property is an object, recursively compare the properties. This will work for any level of nesting. Since the properties could be missing from either of the objects value || {}
check is added.
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
add a comment |
A recursive example,
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a{}
in the results for properties of typeobject
that belong to both objects and that are{}
.
– loretoparisi
12 hours ago
1
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55591096%2fcompare-nested-objects-in-javascript-and-return-keys-equality%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You could use reduce
to build new object and another get
method to get nested props from other object by string
and compare it to current prop value in first object.
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
To compare all properties of both objects you could create extra function that will perform loop by both objects.
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
1
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like{}
, it does not make the comparison.
– loretoparisi
13 hours ago
1
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
Ok, now it handles a nested lonelyprop11={}
object, but if you have like the sameprop12={}
in both, you will get the{}
as result for theprop12
keyword, instead ofbool
. See here jsfiddle.net/gpu20nwy
– loretoparisi
12 hours ago
1
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
|
show 1 more comment
You could use reduce
to build new object and another get
method to get nested props from other object by string
and compare it to current prop value in first object.
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
To compare all properties of both objects you could create extra function that will perform loop by both objects.
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
1
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like{}
, it does not make the comparison.
– loretoparisi
13 hours ago
1
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
Ok, now it handles a nested lonelyprop11={}
object, but if you have like the sameprop12={}
in both, you will get the{}
as result for theprop12
keyword, instead ofbool
. See here jsfiddle.net/gpu20nwy
– loretoparisi
12 hours ago
1
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
|
show 1 more comment
You could use reduce
to build new object and another get
method to get nested props from other object by string
and compare it to current prop value in first object.
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
To compare all properties of both objects you could create extra function that will perform loop by both objects.
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
You could use reduce
to build new object and another get
method to get nested props from other object by string
and compare it to current prop value in first object.
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
To compare all properties of both objects you could create extra function that will perform loop by both objects.
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
const obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } }
const obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" } }
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r
else return r[e] || undefined
}, obj)
}
function compare(a, b, prev = "") {
return Object.keys(a).reduce((r, e) => {
const path = prev + (prev ? '.' + e : e);
const value = a[e] === get(b, path);
r[e] = typeof a[e] === 'object' ? compare(a[e], b, path) : value
return r;
}, {})
}
const result = compare(obj1, obj2);
console.log(result)
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
const obj1 = {"prop1":1,"prop2":"foo","prop3":{"prop4":2,"prop5":"bar"},"prop7":{"prop9":{"prop10":"foo"}}}
const obj2 = {"prop1":3,"prop2":"foo","prop3":{"prop4":2,"prop5":"foobar"},"prop6":"new","prop7":{"foo":"foo","bar":{"baz":"baz"}}}
function get(obj, path) {
return path.split('.').reduce((r, e) => {
if (!r) return r;
else return r[e] || undefined;
}, obj);
}
function isEmpty(o) {
if (typeof o !== 'object') return true;
else return !Object.keys(o).length;
}
function build(a, b, o = null, prev = '') {
return Object.keys(a).reduce(
(r, e) => {
const path = prev + (prev ? '.' + e : e);
const bObj = get(b, path);
const value = a[e] === bObj;
if (typeof a[e] === 'object') {
if (isEmpty(a[e]) && isEmpty(bObj)) {
if (e in r) r[e] = r[e];
else r[e] = true;
} else if (!bObj && isEmpty(a[e])) {
r[e] = value;
} else {
r[e] = build(a[e], b, r[e], path);
}
} else {
r[e] = value;
}
return r;
},
o ? o : {}
);
}
function compare(a, b) {
const o = build(a, b);
return build(b, a, o);
}
const result = compare(obj1, obj2);
console.log(result)
edited 12 hours ago
answered 14 hours ago
Nenad VracarNenad Vracar
73.3k126085
73.3k126085
1
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like{}
, it does not make the comparison.
– loretoparisi
13 hours ago
1
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
Ok, now it handles a nested lonelyprop11={}
object, but if you have like the sameprop12={}
in both, you will get the{}
as result for theprop12
keyword, instead ofbool
. See here jsfiddle.net/gpu20nwy
– loretoparisi
12 hours ago
1
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
|
show 1 more comment
1
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like{}
, it does not make the comparison.
– loretoparisi
13 hours ago
1
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
Ok, now it handles a nested lonelyprop11={}
object, but if you have like the sameprop12={}
in both, you will get the{}
as result for theprop12
keyword, instead ofbool
. See here jsfiddle.net/gpu20nwy
– loretoparisi
12 hours ago
1
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
1
1
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
I thinks this is the best solution since it supports all recent version of ECMAScript.
– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like
{}
, it does not make the comparison.– loretoparisi
13 hours ago
Just a thing, supposed that the property is a void object like
{}
, it does not make the comparison.– loretoparisi
13 hours ago
1
1
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
In that case you could use this jsfiddle.net/vqwn3zLf
– Nenad Vracar
13 hours ago
Ok, now it handles a nested lonely
prop11={}
object, but if you have like the same prop12={}
in both, you will get the {}
as result for the prop12
keyword, instead of bool
. See here jsfiddle.net/gpu20nwy– loretoparisi
12 hours ago
Ok, now it handles a nested lonely
prop11={}
object, but if you have like the same prop12={}
in both, you will get the {}
as result for the prop12
keyword, instead of bool
. See here jsfiddle.net/gpu20nwy– loretoparisi
12 hours ago
1
1
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
@loretoparisi Try this jsfiddle.net/r0y8nd3q/1
– Nenad Vracar
12 hours ago
|
show 1 more comment
You could iterate all keys and check the nested objects if both values are objects.
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
Thanks! This solution works in every condition even if the property is a void object likeprop7 = {}
. Maybe avoiding the ECMA6Spread
notation for more compatibility could help.
– loretoparisi
13 hours ago
1
without spread notSet
.
– Nina Scholz
13 hours ago
maybe likeObject.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
1
w h a t e v e r ...
– Nina Scholz
13 hours ago
add a comment |
You could iterate all keys and check the nested objects if both values are objects.
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
Thanks! This solution works in every condition even if the property is a void object likeprop7 = {}
. Maybe avoiding the ECMA6Spread
notation for more compatibility could help.
– loretoparisi
13 hours ago
1
without spread notSet
.
– Nina Scholz
13 hours ago
maybe likeObject.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
1
w h a t e v e r ...
– Nina Scholz
13 hours ago
add a comment |
You could iterate all keys and check the nested objects if both values are objects.
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
You could iterate all keys and check the nested objects if both values are objects.
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
const isObject = v => v && typeof v === 'object';
function getDifference(a, b) {
return Object.assign(...Array.from(
new Set([...Object.keys(a), ...Object.keys(b)]),
k => ({ [k]: isObject(a[k]) && isObject(b[k])
? getDifference(a[k], b[k])
: a[k] === b[k]
})
));
}
var obj1 = { prop1: 1, prop2: "foo", prop3: { prop4: 2, prop5: "bar" } },
obj2 = { prop1: 3, prop2: "foo", prop3: { prop4: 2, prop5: "foobar" }, prop6: "new" };
console.log(getDifference(obj1, obj2));
edited 14 hours ago
answered 14 hours ago
Nina ScholzNina Scholz
197k15109179
197k15109179
Thanks! This solution works in every condition even if the property is a void object likeprop7 = {}
. Maybe avoiding the ECMA6Spread
notation for more compatibility could help.
– loretoparisi
13 hours ago
1
without spread notSet
.
– Nina Scholz
13 hours ago
maybe likeObject.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
1
w h a t e v e r ...
– Nina Scholz
13 hours ago
add a comment |
Thanks! This solution works in every condition even if the property is a void object likeprop7 = {}
. Maybe avoiding the ECMA6Spread
notation for more compatibility could help.
– loretoparisi
13 hours ago
1
without spread notSet
.
– Nina Scholz
13 hours ago
maybe likeObject.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
1
w h a t e v e r ...
– Nina Scholz
13 hours ago
Thanks! This solution works in every condition even if the property is a void object like
prop7 = {}
. Maybe avoiding the ECMA6 Spread
notation for more compatibility could help.– loretoparisi
13 hours ago
Thanks! This solution works in every condition even if the property is a void object like
prop7 = {}
. Maybe avoiding the ECMA6 Spread
notation for more compatibility could help.– loretoparisi
13 hours ago
1
1
without spread not
Set
.– Nina Scholz
13 hours ago
without spread not
Set
.– Nina Scholz
13 hours ago
maybe like
Object.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
maybe like
Object.assign(Array.from(new Set( .concat(Object.keys(a)).concat(Object.keys(b)))
– loretoparisi
13 hours ago
1
1
w h a t e v e r ...
– Nina Scholz
13 hours ago
w h a t e v e r ...
– Nina Scholz
13 hours ago
add a comment |
Loop through each key and compare the properties. If the property is an object, recursively compare the properties. This will work for any level of nesting. Since the properties could be missing from either of the objects value || {}
check is added.
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
add a comment |
Loop through each key and compare the properties. If the property is an object, recursively compare the properties. This will work for any level of nesting. Since the properties could be missing from either of the objects value || {}
check is added.
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
add a comment |
Loop through each key and compare the properties. If the property is an object, recursively compare the properties. This will work for any level of nesting. Since the properties could be missing from either of the objects value || {}
check is added.
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
Loop through each key and compare the properties. If the property is an object, recursively compare the properties. This will work for any level of nesting. Since the properties could be missing from either of the objects value || {}
check is added.
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
const obj1={prop1:1,prop2:"foo",prop3:{prop4:2,prop5:"bar"},prop7:{pro8:"only in 1"}},
obj2={prop1:3,prop2:"foo",prop3:{prop4:2,prop5:"foobar"}, prop6: "only in 2"};
const isObject = val => val && typeof val === 'object'; // required for "null" comparison
function compare(obj1, obj2) {
let equality = {},
merged = { ...obj1, ...obj2 }; // has properties of both
for (let key in merged) {
let value1 = obj1[key], value2 = obj2[key];
if (isObject(value1) || isObject(value2)) {
equality[key] = compare(value1 || {}, value2 || {});
} else {
equality[key] = value1 === value2
}
}
return equality;
}
console.log(compare(obj1, obj2))
edited 13 hours ago
answered 14 hours ago
adigaadiga
12.3k62645
12.3k62645
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
add a comment |
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
Thanks, just updated the code, assuming you can have new properties as well.
– loretoparisi
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
what if obj1 have some key with a child obj as its value and obj2 does not have the same key, then the method will be called with compare(obj1, undefined) which will throw an error at obj2[key]
– AZ_
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@loretoparisi updated
– adiga
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@adiga not sure, but the comments in the question do mention that, and the updated question as well, it cant be assumed that extra ket always have a string value.
– AZ_
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
@AZ_ updated. Not sure if it will fail for any scenario
– adiga
14 hours ago
add a comment |
A recursive example,
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a{}
in the results for properties of typeobject
that belong to both objects and that are{}
.
– loretoparisi
12 hours ago
1
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
add a comment |
A recursive example,
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a{}
in the results for properties of typeobject
that belong to both objects and that are{}
.
– loretoparisi
12 hours ago
1
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
add a comment |
A recursive example,
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
A recursive example,
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
var obj1 = {
prop1: 1,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "bar"
},
prop7: {},
}
var obj2 = {
prop1: 3,
prop2: "foo",
prop3: {
prop4: 2,
prop5: "foobar"
},
prop6: "new",
prop7: {},
prop8: {},
}
var result = {};
function compare(obj1, obj2, obj_) {
for (let k in obj1) {
var type = typeof obj1[k];
if (type === 'object') {
obj_[k] = {};
if (!obj2[k]){
obj_[k] = false;
}else if ((Object.entries(obj1[k]).length === 0 && obj1[k].constructor === Object) && (Object.entries(obj2[k]).length === 0 && obj2[k].constructor === Object)) {
obj_[k] = true;
} else {
compare(obj1[k], obj2[k], obj_[k]);
}
} else {
obj_[k] = (obj1[k] === obj2[k]);
}
}
}
if (Object.keys(obj1).length < Object.keys(obj2).length) { //check if both objects vary in length.
var tmp = obj1;
obj1 = obj2;
obj2 = tmp;
}
compare(obj1, obj2, result);
console.log(result);
edited 12 hours ago
answered 13 hours ago
Shoyeb SheikhShoyeb Sheikh
662211
662211
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a{}
in the results for properties of typeobject
that belong to both objects and that are{}
.
– loretoparisi
12 hours ago
1
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
add a comment |
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a{}
in the results for properties of typeobject
that belong to both objects and that are{}
.
– loretoparisi
12 hours ago
1
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a
{}
in the results for properties of type object
that belong to both objects and that are {}
.– loretoparisi
12 hours ago
Thank you. If you try this case - jsfiddle.net/47fcqtom you will get a
{}
in the results for properties of type object
that belong to both objects and that are {}
.– loretoparisi
12 hours ago
1
1
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
@loretoparisi I made a change, try now.
– Shoyeb Sheikh
12 hours ago
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55591096%2fcompare-nested-objects-in-javascript-and-return-keys-equality%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Will both objects always have exact match properties?
– holydragon
14 hours ago
good point. Nope, so the equality could have a new key set to
false
. Updating with this point. Thank you.– loretoparisi
14 hours ago