首页 > 解决方案 > 在嵌套对象中查找相似之处

问题描述

假设我有:

const a = {
  'prkn': {
    tec: [ 'Coding', 'Machine Learning', 'Cloud Development' ],
    des: [ 'Web Design' ]
  },
  'pekn': { cu: [ 'Musica', 'Cinema', 'Arte' ] }
}

const b = {
  'prkn': {
    tec: [
      'Coding',
      'Machine Learning',
      'Cloud Development',
      'IoT Management'
    ],
    des: [ 'UX/UI', 'Web Design', 'Prototyping', 'Design Thinking' ]
  },
  'pekn': { cu: [ 'Cinema', 'Lettura' ] }
}

我想要这些对象的交集:

{
  'prkn': {
    tec: [ 'Coding', 'Machine Learning', 'Cloud Development' ],
    des: [ 'Web Design' ]
  },
  'pekn': { cu: [ 'Cinema' ] }
}

这是代码,但它不起作用..:

const a = {
  'prkn': {
    tec: [ 'Coding', 'Machine Learning', 'Cloud Development' ],
    des: [ 'Web Design' ]
  },
  'pekn': { cu: [ 'Musica', 'Cinema', 'Arte' ] }
}

const b = {
  'prkn': {
    tec: [
      'Coding',
      'Machine Learning',
      'Cloud Development',
      'IoT Management'
    ],
    des: [ 'UX/UI', 'Web Design', 'Prototyping', 'Design Thinking' ]
  },
  'pekn': { cu: [ 'Cinema', 'Lettura' ] }
}

function findSimilarities(obj1, obj2) {
  const bo1 = Object.entries(obj1).reduce((acc1, [l1, v1]) => {
    const bo2 = Object.entries(v1).reduce((acc2, [l2, v2]) => {
      const sim = v2.filter(s => obj2[l1][l2].includes(s))
      acc2[l2] = sim
      return acc2
    })
    acc1[l1] = bo2
    return acc1
  }, {})
 return bo1
}

console.log(findSimilarities(a, b))

标签: javascript

解决方案


这是一个相当简单的示例,适用于您的给定数据。

它首先与Object.keys()传递的对象相交并根据typeof它们关联的属性过滤它们,这样我们就不会浪费时间比较未共享的键或类型不匹配的键。然后它遍历这些键,如果它们引用它递归的对象(但不是数组),否则如果两者都是数组与它们相交(这里使用includes()嵌套对象将不起作用),最后检查基本相等性。设置acc[key]并返回。

const
  a = { 'prkn': { red: 1, bl: null, tec: ['Coding', 'Machine Learning', 'Cloud Development'], des: ['Web Design'] }, 'pekn': { cu: ['Musica', 'Cinema', 'Arte'] } },
  b = { 'prkn': { red: 1, bl: 'Dog', tec: ['Coding', 'Machine Learning', 'Cloud Development', 'IoT Management'], des: ['UX/UI', 'Web Design', 'Prototyping', 'Design Thinking'] }, 'pekn': { cu: ['Cinema', 'Lettura'] } },

  intersectPrimitiveArrays = (a, b) => a.filter(e => b.includes(e)),

  intersectObjects = (a, b) => {
    const keys = intersectPrimitiveArrays(Object.keys(a), Object.keys(b))
      .filter(k => (typeof a[k]) === (typeof b[k]));

    return keys.reduce((acc, key) => {
      const
        _a = a[key],
        _b = b[key];

      let element = _a;

      if (typeof _a === 'object' && (_a !== null || _b !== null) && (!Array.isArray(_a) && !Array.isArray(_b))) {
        element = intersectObjects(_a, _b);
      } else if (Array.isArray(_a) && Array.isArray(_b)) {
        element = intersectPrimitiveArrays(_a, _b);
      } else if (_a !== _b) {
        element = undefined;
      }

      if (element !== undefined) {
        acc[key] = element;
      }

      return acc;
    }, {})
  }

console.log(intersectObjects(a, b));
.as-console-wrapper { max-height: 100% !important; top: 0; }


推荐阅读