Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection of two deep objects in JavaScript

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!

like image 661
christianbundy Avatar asked Aug 28 '18 17:08

christianbundy


1 Answers

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; }
like image 86
Nina Scholz Avatar answered Sep 30 '22 06:09

Nina Scholz