繁体   English   中英

JavaScript中两个深层对象的交集

[英]Intersection of two deep objects in JavaScript

我有两个具有大量相同信息的JavaScript对象(任意深度)。

我正在寻找帮助获取两个对象之间的共享数据

例如:

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

我的目标是提出一个解决方案来生成他们共享的数据:

const shared = {
  features: {
    speed: 3,
    mind: {
      power: 42
    }
  }
}

我正在操作的真实数据是任意深度嵌套的(通常是对象中的几十个对象),但我希望上面的例子很有帮助。

这是一次性的任务,所以我并不特别关心性能,只要它有效,我很乐意使用任何库。 谢谢您的帮助!

您可以通过检查两个对象中属性的存在,truthy属性和相同的对象类型或相同的值来使用recursve方法。

使用变量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; } 

您可以for...in迭代中使用for...in循环遍历对象并检查它的属性。 请参阅下面的代码,看看你想要的是什么。

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

当一个对象值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