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







7















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










share|improve this question




















  • 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




















7















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










share|improve this question




















  • 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
















7












7








7


1






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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 to false. Updating with this point. Thank you.

    – loretoparisi
    14 hours ago
















  • 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










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














4 Answers
4






active

oldest

votes


















1














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)








share|improve this answer





















  • 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 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





    @loretoparisi Try this jsfiddle.net/r0y8nd3q/1

    – Nenad Vracar
    12 hours ago



















5














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








share|improve this answer


























  • 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





    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






  • 1





    w h a t e v e r ...

    – Nina Scholz
    13 hours ago



















2














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








share|improve this answer


























  • 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



















1














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








share|improve this answer


























  • 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





    @loretoparisi I made a change, try now.

    – Shoyeb Sheikh
    12 hours ago












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


}
});














draft saved

draft discarded


















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









1














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)








share|improve this answer





















  • 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 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





    @loretoparisi Try this jsfiddle.net/r0y8nd3q/1

    – Nenad Vracar
    12 hours ago
















1














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)








share|improve this answer





















  • 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 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





    @loretoparisi Try this jsfiddle.net/r0y8nd3q/1

    – Nenad Vracar
    12 hours ago














1












1








1







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)








share|improve this answer















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)






share|improve this answer














share|improve this answer



share|improve this answer








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





    @loretoparisi Try this jsfiddle.net/r0y8nd3q/1

    – Nenad Vracar
    12 hours ago














  • 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 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





    @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













5














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








share|improve this answer


























  • 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





    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






  • 1





    w h a t e v e r ...

    – Nina Scholz
    13 hours ago
















5














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








share|improve this answer


























  • 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





    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






  • 1





    w h a t e v e r ...

    – Nina Scholz
    13 hours ago














5












5








5







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








share|improve this answer















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






share|improve this answer














share|improve this answer



share|improve this answer








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 like prop7 = {}. Maybe avoiding the ECMA6 Spread notation for more compatibility could help.

    – loretoparisi
    13 hours ago








  • 1





    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






  • 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








  • 1





    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






  • 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











2














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








share|improve this answer


























  • 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
















2














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








share|improve this answer


























  • 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














2












2








2







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








share|improve this answer















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






share|improve this answer














share|improve this answer



share|improve this answer








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



















  • 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











1














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








share|improve this answer


























  • 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





    @loretoparisi I made a change, try now.

    – Shoyeb Sheikh
    12 hours ago
















1














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








share|improve this answer


























  • 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





    @loretoparisi I made a change, try now.

    – Shoyeb Sheikh
    12 hours ago














1












1








1







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








share|improve this answer















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






share|improve this answer














share|improve this answer



share|improve this answer








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 type object 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








  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Masuk log Menu navigasi

Identifying “long and narrow” polygons in with PostGISlength and width of polygonWhy postgis st_overlaps reports Qgis' “avoid intersections” generated polygon as overlapping with others?Adjusting polygons to boundary and filling holesDrawing polygons with fixed area?How to remove spikes in Polygons with PostGISDeleting sliver polygons after difference operation in QGIS?Snapping boundaries in PostGISSplit polygon into parts adding attributes based on underlying polygon in QGISSplitting overlap between polygons and assign to nearest polygon using PostGIS?Expanding polygons and clipping at midpoint?Removing Intersection of Buffers in Same Layers

Старые Смолеговицы Содержание История | География | Демография | Достопримечательности | Примечания | НавигацияHGЯOLHGЯOL41 206 832 01641 606 406 141Административно-территориальное деление Ленинградской области«Переписная оброчная книга Водской пятины 1500 года», С. 793«Карта Ингерманландии: Ивангорода, Яма, Копорья, Нотеборга», по материалам 1676 г.«Генеральная карта провинции Ингерманландии» Э. Белинга и А. Андерсина, 1704 г., составлена по материалам 1678 г.«Географический чертёж над Ижорскою землей со своими городами» Адриана Шонбека 1705 г.Новая и достоверная всей Ингерманландии ланткарта. Грав. А. Ростовцев. СПб., 1727 г.Топографическая карта Санкт-Петербургской губернии. 5-и верстка. Шуберт. 1834 г.Описание Санкт-Петербургской губернии по уездам и станамСпецкарта западной части России Ф. Ф. Шуберта. 1844 г.Алфавитный список селений по уездам и станам С.-Петербургской губернииСписки населённых мест Российской Империи, составленные и издаваемые центральным статистическим комитетом министерства внутренних дел. XXXVII. Санкт-Петербургская губерния. По состоянию на 1862 год. СПб. 1864. С. 203Материалы по статистике народного хозяйства в С.-Петербургской губернии. Вып. IX. Частновладельческое хозяйство в Ямбургском уезде. СПб, 1888, С. 146, С. 2, 7, 54Положение о гербе муниципального образования Курское сельское поселениеСправочник истории административно-территориального деления Ленинградской области.Топографическая карта Ленинградской области, квадрат О-35-23-В (Хотыницы), 1930 г.АрхивированоАдминистративно-территориальное деление Ленинградской области. — Л., 1933, С. 27, 198АрхивированоАдминистративно-экономический справочник по Ленинградской области. — Л., 1936, с. 219АрхивированоАдминистративно-территориальное деление Ленинградской области. — Л., 1966, с. 175АрхивированоАдминистративно-территориальное деление Ленинградской области. — Лениздат, 1973, С. 180АрхивированоАдминистративно-территориальное деление Ленинградской области. — Лениздат, 1990, ISBN 5-289-00612-5, С. 38АрхивированоАдминистративно-территориальное деление Ленинградской области. — СПб., 2007, с. 60АрхивированоКоряков Юрий База данных «Этно-языковой состав населённых пунктов России». Ленинградская область.Административно-территориальное деление Ленинградской области. — СПб, 1997, ISBN 5-86153-055-6, С. 41АрхивированоКультовый комплекс Старые Смолеговицы // Электронная энциклопедия ЭрмитажаПроблемы выявления, изучения и сохранения культовых комплексов с каменными крестами: по материалам работ 2016-2017 гг. в Ленинградской области