javascriptobjectecmascript-6ecmascript-2016

getting difference object from two objects using es6


Im trying to figure out whats the best way to get an intersection object between two objects using es6. by this i mean something like:

a = {a:'a',b:'b',c:'c', d:'d'};
b = {a:'a',b: '1', c:'c', d:'2', f'!!!'}
// result I want:
c = getDifference(a,b)
//c is now: {b:'1', d:'2'}

Is there a short way to do this using es6, or do I need to iterate over the a object using for(in) with Object.keys() and compare, assigning intersections to c?

(a,b) => {
    const c = {};
    for(const _key in Object.keys(a)){
       if(b[_key] && b[_key] !== a[_key]){
           c[_key] = b[_key];
       }
    }
    return c;
}

I know loadash/underscore has these kinds of helper functions... but trying to see if es6 has any new short syntax for this, and if not whats the shortest way to do this using vanilla js.


Solution

  • You can get the entries of object b using Object.entries() and then filter out the key-value pairs which are the same as those in a using .filter(), then, you can rebuild your object using Object.fromEntries() like so:

    const a = {a:'a',b:'b',c:'c', d:'d'};
    const b = {a:'a',b: '1', c:'c', d:'2', f:'!!!'}
    
    const getDifference = (a, b) => 
      Object.fromEntries(Object.entries(b).filter(([key, val]) => key in a && a[key] !== val));
    
    
    // result I want:
    const c = getDifference(a,b); // peforms b-a
    console.log(c); // {b:'1', d:'2'}

    If you can't support Object.fromEntries(), then you can use .reduce() instead to build the object for you:

    const a = {a:'a',b:'b',c:'c', d:'d'};
    const b = {a:'a',b: '1', c:'c', d:'2', f:'!!!'}
    
    const getDifference = (a, b) => 
      Object.entries(b).filter(([key, val]) => a[key] !== val && key in a).reduce((a, [key, v]) => ({...a, [key]: v}), {});
    
    
    // result I want:
    const c = getDifference(a,b); // peforms b-a
    console.log(c); // {b:'1', d:'2'}