Reputation: 674
I have two JavaScript objects (of arbitrary depth) that have much of the same information.
I'm looking for help getting the shared data between two objects.
For example:
const a = {
name: 'Alice',
features: {
speed: 3,
strength: 90,
mind: {
power: 42
}
}
};
const b = {
name: 'Bob',
features: {
speed: 3,
stamina: 1,
mind: {
power: 42,
flexibility: 0,
telekinesis: 42
}
}
};
My goal is to come up with a solution to produce the data that they share:
const shared = {
features: {
speed: 3,
mind: {
power: 42
}
}
}
The real data I'm operating on is nested arbitrarily deep (often dozens of objects within objects), but I'm hoping the above examples are helpful.
This is a one-off task so I'm not particularly concerned with performance, and I'm happy to use any library as long as it works. Thanks for the help!
Upvotes: 5
Views: 3120
Reputation: 674
It looks like the other answers in this thread crashed when an object value was undefined
, so I combined the best parts of each answer to come up with a robust solution:
const isObj = x => typeof x === 'object'
const common = (a, b) => {
let result = {}
if (([a, b]).every(isObj)) {
Object.keys(a).forEach((key) => {
const value = a[key]
const other = b[key]
if (isObj(value)) {
result[key] = common(value, other)
} else if (value === other) {
result[key] = value
}
})
}
return result
}
Upvotes: 1
Reputation: 386756
You could use an recursve approach by checking the existence of properties in both objects, truthy properties and same object type or same values.
The use of a variable temp
prevents empty nested objects.
function common(object1, object2) {
return Object.assign(...Object.keys(object1).map(k => {
var temp;
if (!(k in object2)) {
return {};
}
if (object1[k] && typeof object1[k] === 'object' &&
object2[k] && typeof object2[k] === 'object') {
temp = common(object1[k], object2[k]);
return Object.keys(temp).length ? { [k]: temp } : {};
}
if (object1[k] === object2[k]) {
return { [k]: object1[k] };
}
return {};
}));
}
const
a = { name: 'Alice', features: { speed: 3, strength: 90, mind: { power: 42 } } };
b = { name: 'Bob', features: { speed: 3, stamina: 1, mind: { power: 42, flexibility: 0, telekinesis: 42 } } };
console.log(common(a, b));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 4
Reputation: 6501
You can use the for...in
iteration to loop through the object and check it's properties.
Please, see in the below code if is that what you want.
const a = {
name: 'Alice',
features: {
speed: 3,
strength: 90,
mind: {
power: 42
}
}
};
const b = {
name: 'Bob',
features: {
speed: 3,
stamina: 1,
mind: {
power: 42,
flexibility: 0,
telekinesis: 42
}
}
};
function equalProps(a,b){
var newObj = {};
for (var key in a){
if (typeof a[key] === 'object'){
var obj = equalProps(a[key], b[key]);
newObj[key] = obj;
}else if (a[key] == b[key]){
newObj[key] = a[key];
}
}
return newObj;
}
console.log(equalProps(a,b))
Upvotes: 1