Question is similar to: How can I check that two objects have the same set of property names? but only one difference
I want to check:
var objOne = {"a":"one","b":"two","c":{"f":"three_one"}};
var objTwo = {"a":"four","b":"five","c":{"f":"six_one"}};
have the same set of keys in all level?
For example deepCheckObjKeys(objOne, objTwo)
would return true
where deepCheckObjKeys(objOne, objThree)
return false
, if:
var objThree = {"a":"four","b":"five","c":{"g":"six_one"}};
Since objThree.a.c.f
is undefined
in objThree.
A function like this:
'use strict';
function objectsHaveSameKeys() {
for (var _len = arguments.length, objects = Array(_len), _key = 0; _key < _len; _key++) {
objects[_key] = arguments[_key];
}
var allKeys = objects.reduce(function (keys, object) {
return keys.concat(Object.keys(object));
}, []);
var union = new Set(allKeys);
return objects.every(function (object) {
return union.size === Object.keys(object).length;
});
}
only checks the first level.
PS: objectsHaveSameKeys() ES6 equivalent:
function objectsHaveSameKeys(...objects):boolean {
const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
const union = new Set(allKeys);
return objects.every(object => union.size === Object.keys(object).length);
}
Approach: We will find keys of both objects by Object. keys(), which returns an array of keys of that object. For checking that every key in obj1 is also present in obj2, and if values of those key matches, we will use every() method.
No, JavaScript objects cannot have duplicate keys. The keys must all be unique.
equals function will determine if two objects are equal.
There are mainly two methods to check the existence of a key in JavaScript Object. The first one is using “in operator” and the second one is using “hasOwnProperty() method”. Method 1: Using 'in' operator: The in operator returns a boolean value if the specified property is in the object.
I'd do a recursive check if a property's value is an object.
There's an interesting wrinkle here; actually, there are (at least) two:
null
and the other has no properties? true
or false
?{a: null}
and the other has {a: 17}
? true
or false
?{a: null}
and the other has {a: {}}
? true
or false
?For the purposes of this example, I've treated null
like an object with no properties, but it's very much dependent on your use case. I can think of at least two other ways to go (null
doesn't match anything but null
, or null
doesn't match anything but a non-object, even if the object has no own properties) and there are probably others.
See comments:
const deepSameKeys = (o1, o2) => {
// Both nulls = same
if (o1 === null && o2 === null) {
return true;
}
// Get the keys of each object
const o1keys = o1 === null ? new Set() : new Set(Object.keys(o1));
const o2keys = o2 === null ? new Set() : new Set(Object.keys(o2));
if (o1keys.size !== o2keys.size) {
// Different number of own properties = not the same
return false;
}
// Look for differences, recursing as necessary
for (const key of o1keys) {
if (!o2keys.has(key)) {
// Different keys
return false;
}
// Get the values and their types
const v1 = o1[key];
const v2 = o2[key];
const t1 = typeof v1;
const t2 = typeof v2;
if (t1 === "object") {
if (t2 === "object" && !deepSameKeys(v1, v2)) {
return false;
}
} else if (t2 === "object") {
// We know `v1` isn't an object
return false;
}
}
// No differences found
return true;
};
// Checking your example
const objOne = {"a": "one", "b": "two", "c": {"f": "three_one"}};
const objTwo = {"a": "four", "b": "five", "c": {"f": "six_one"}};
const objThree = {"a": "four", "b": "five", "c": {"g": "six_one"}};
console.log("objOne vs. objTwo: ", deepSameKeys(objOne, objTwo)); // true
console.log("objTwo vs. objThree: ", deepSameKeys(objTwo, objThree)); // false
// `null` checks
console.log("{a: null} vs. {a: 17} ", deepSameKeys({a: null}, {a: 17})); // true
console.log("{a: null} vs. {a: {}} ", deepSameKeys({a: null}, {a: {}})); // true -- depending on your use case, you may want this to be false
console.log("{a: null} vs. {a: {x:1}} ", deepSameKeys({a: null}, {a: {x:1}})); // false
// Differing value type check
console.log("{a: 1} vs. {a: '1'}} ", deepSameKeys({a: 1}, {a: '1'})); // true
I guess you're looking for a deep-check version of the function provided [here] :)(How can I check that two objects have the same set of property names?).
Below is my attempt. Please note:
function objectsHaveSameKeys(...objects) {
const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), [])
const union = new Set(allKeys)
if (union.size === 0) return true
if (!objects.every((object) => union.size === Object.keys(object).length)) return false
for (let key of union.keys()) {
let res = objects.map((o) => (typeof o[key] === 'object' ? o[key] : {}))
if (!objectsHaveSameKeys(...res)) return false
}
return true
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With