7

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.

4
  • 4
    Common misconception debunked - ES6 is vanilla JavaScript. Commented Aug 27, 2019 at 7:32
  • yes... I know... I say Es6 to emphasize that im talking about es6 and above since both es6 & es7 has a lot of new features maybe im missing a short way to do this... Commented Aug 27, 2019 at 7:35
  • 3
    Shouldn't c have also f key? It's unclear what you mean by "difference". Do you need to get differences of a against b and vice-versa or just one against the other? Also, how would you handle nested objects?.. Commented Aug 27, 2019 at 7:37
  • ammm... no I should of probably used the word -intersection- instead of -difference- I'll edit this Commented Aug 27, 2019 at 7:38

3 Answers 3

14

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'}

Sign up to request clarification or add additional context in comments.

3 Comments

second solution works out of the box... and you provided future solution... nice
Doesn't work with nested objects.
@Ariakas You can modify the answer above to use recursion to make it work with deeply nested objects (that was out of scope for this question, so not included in my answer). See this question for details: Generic deep diff between two objects
6

Use reduce for more concise code, but your approach was the clearest:

const getDifference = (a, b) => Object.entries(a).reduce((ac, [k, v]) => b[k] && b[k] !== v ? (ac[k] = b[k], ac) : ac, {});

We use Object.entries to avoid getting the value if we used Object.keys - it's just easier. Since b[k] may not exist, we use the short-circuit logical AND && operator - so if a key from a doesn't exist in b, it's not added to the result object. Then we check if the two values are equal - if they are, then nothing needs to be added, but if they're not, we add the key and value from b to the result object. In both cases, we return the result object.

7 Comments

Upvoting since you're the only one that actually mentioned that your solution has no benefits other than being more concise than the original one (neither more efficient, nor actually much conceptually different).
Thanks @briosheje, always good to know I'm getting stuff right!
Can you explain your code a bit? I can't get it :/ Looks like a nice approach
Done @weegee, how's that?
No worries @weegee, always glad to help.
|
0

You can achieve this in a single short with Object.keys();

const mainObj = {
  a: 'a', b: 'b', c: 'c', d: 'd',
};
const comapareObj = {
  a: 'a', b: '1', c: 'c', d: '2', f: '!!!',
};

const findVariantsElement = (main, compareWith) => {
  const result = {};
  Object.keys(main).forEach((r) => {
    const element = main[r];
    if (compareWith[r]) {
      if (element !== compareWith[r]) {
        result[r] = compareWith[r];
      }
    }
  });
  return result;
};

const c = findVariantsElement(mainObj, comapareObj);
console.log(c); 

You can use .map() also for the same

const mainObj = {
  a: 'a', b: 'b', c: 'c', d: 'd',
};
const comapareObj = {
  a: 'a', b: '1', c: 'c', d: '2', f: '!!!',
};

const findVariantsElement = (main, compareWith) => {
  const result = {};
  Object.keys(main).map((r) => {
    const element = main[r];
    if (compareWith[r]) {
      if (element !== compareWith[r]) {
        result[r] = compareWith[r];
      }
    }
  });
  return result;
};

const c = findVariantsElement(mainObj, comapareObj);
console.log(c); 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.