getting difference object from two objects using es6

不打扰是莪最后的温柔 提交于 2019-12-11 19:10:40

问题


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.


回答1:


You can get the entries of object b using Object.entries() and then filter out the key-value pairs which are the same 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 (but only gives properties from both a and b)
console.log(c); // {b:'1', d:'2'}

However, Object.fromEntries() is currently in draft mode, and so you may use .reduce() instead:

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 (but only gives properties from both a and b)
console.log(c); // {b:'1', d:'2'}



回答2:


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.




回答3:


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); 


来源:https://stackoverflow.com/questions/57669696/getting-difference-object-from-two-objects-using-es6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!