简体   繁体   English

JavaScript中两个深层对象的交集

[英]Intersection of two deep objects in JavaScript

I have two JavaScript objects (of arbitrary depth) that have much of the same information. 我有两个具有大量相同信息的JavaScript对象(任意深度)。

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! 谢谢您的帮助!

You could use an recursve approach by checking the existence of properties in both objects, truthy properties and same object type or same values. 您可以通过检查两个对象中属性的存在,truthy属性和相同的对象类型或相同的值来使用recursve方法。

The use of a variable temp prevents empty nested objects. 使用变量temp可以防止空嵌套对象。

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

You can use the for...in iteration to loop through the object and check it's properties. 您可以for...in迭代中使用for...in循环遍历对象并检查它的属性。 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)) 

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: 当一个对象值undefined时,看起来这个线程中的其他答案崩溃了,所以我将每个答案的最佳部分组合起来得出一个强大的解决方案:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM