Reputation: 93
I need to check if two object have common sub-objects. By common I mean that it exact same value, and not just equal values.
Something like:
function haveCommonObects(value1, value2) {
...
}
var common = {};
haveCommonObjects({a: common}, {b: {c: common}}) // true
haveCommonObjects({a: 1}, {b: 1}) // false
I need to check large objects, so function should be reasonable efficient.
Also I can't change objects, so I can't flag sub-objects with special property. Objects create in 3rd-party library so I can't alter Object.prototype
.
Ideal solution would be to get some kind of ID for every object and save it in collection that support fast lookup.
Can I make such function in JS?
Upvotes: 0
Views: 106
Reputation: 35314
Here's how I would do this:
function haveCommonObjects(a,b) {
// check if a and b have any object in common, at any depth level
if (typeof(a) !== 'object' || typeof(b) !== 'object') return false;
for (var key in a) {
var o = a[key];
if (typeof(o) === 'object' && (hasObject(b,o) || haveCommonObjects(o,b)))
return true;
}
return false;
}
function hasObject(x,t) {
// check if x has a reference to object t, at any depth level
for (var key in x) {
var o = x[key];
if (typeof(o) === 'object' && (o === t || hasObject(o,t)))
return true;
}
return false;
}
function log(msg) { document.getElementById('log').innerHTML += msg+'<br/>'; }
var common = {};
log(haveCommonObjects({a: common}, {b: {c: common}})); // true
log(haveCommonObjects({a: 1}, {b: 1})); // false
<div id="log"></div>
Note: You should add a hasOwnProperty()
filter in every for..in loop if you want to exclude inherited properties; see for..in and hasOwnProperty.
Upvotes: 1