【问题标题】:Intersection of two deep objects in JavaScriptJavaScript 中两个深层对象的交集
【发布时间】:2019-02-03 09:23:20
【问题描述】:

我有两个 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
    }
  }
}

我正在操作的真实数据嵌套任意深(通常是几十个对象内的对象),但我希望以上示例有所帮助。

这是一项一次性任务,因此我并不特别关心性能,而且我很乐意使用任何库,只要它可以工作。感谢您的帮助!

【问题讨论】:

    标签: javascript object nested javascript-objects


    【解决方案1】:

    您可以使用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))

    【讨论】:

      【解决方案2】:

      您可以通过检查两个对象中是否存在属性、真实属性以及相同的对象类型或相同的值来使用递归方法。

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

      【讨论】:

        【解决方案3】:

        当对象值为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
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-13
          • 1970-01-01
          • 2019-02-20
          • 1970-01-01
          • 1970-01-01
          • 2018-06-22
          • 2022-11-25
          • 2018-09-04
          相关资源
          最近更新 更多