如何在两个对象数组之间创建交集

3
我正试图对两个对象数组进行交集操作。 https://codesandbox.io/s/friendly-bohr-v73ob?fbclid=IwAR3yQDnftREENi8lF6wCKYE_F09pimlLgfYca0B_oIPqYYHvbAf4cvnG-n4
const list1 = [
  {
    name: "skinType",
    keys: [
      {
        id: "oily",
        label: "Oily"
      },
      {
        id: "dry",
        label: "Dry"
      }
    ]
  },
  {
    name: "finish",
    keys: [
      {
        id: "oily",
        label: "Oily"
      },
      {
        id: "dry",
        label: "Dry"
      },
      {
        id: "matte",
        label: "Matte"
      },
      {
        id: "natural",
        label: "Natural"
      },
      {
        id: "radiant",
        label: "Radiant / Glow"
      }
    ]
  },
  {
    name: "texture",
    keys: [
      {
        id: "matte",
        labal: "Matte"
      }
    ]
  }
];

const list2 = [
  {
    name: "skinType",
    keys: [
      {
        id: "oily",
        label: "Oily"
      },
      {
        id: "dry",
        label: "Dry"
      },
      {
        id: "gandac",
        label: "mazga"
      }
    ]
  },
  {
    name: "finish",
    keys: [
      {
        id: "oily",
        label: "Oily"
      }
    ]
  }
];

我想到了一个解决方案,但它只能根据对象的名称键进行交集运算。现在,我需要根据键数组中的id执行交集运算。

const intersection = (list1, list2) => {
  return list2.filter(drp => list1.some(rect => rect.name === drp.name));
};

const result = intersection(react, drupal);

期望的结果:

[
  {
    name: "skinType",
    keys: [
      {
        id: "oily",
        label: "Oily"
      },
      {
        id: "dry",
        label: "Dry"
      }
    ]
  },
  {
    name: "finish",
    keys: [
      {
        id: "oily",
        label: "Oily"
      }
    ]
  }
]

请在您的问题中直接包含所有相关代码和其他信息。外部链接随时间可能会失效(并且通常确实如此)。 - Tim Biegeleisen
你能添加新的预期结果吗?它会包含一个名为“texture”的对象吗?如果是,请添加,因为当前的预期结果不包含它。看起来给定的预期输出是基于名称而不是键数组中的ID。 - Reetesh Kumar
预期结果不应包含纹理对象,因为它在两个列表中都不存在。 - aircraft721
如果它是 @aircraft721 的 Union 类型,则必须是两个列表的联合。 - Reetesh Kumar
这不是Union,@aircraft721我想你是指两个列表的交集。 - prisar
是的,我的错。我编辑了问题。谢谢@ReeteshKumar。 - aircraft721
3个回答

1

const react = [
  { name: "skinType", 
    keys: [
      { id: "oily", label: "Oily" },
      { id: "dry",  label: "Dry" }
    ]
  },
  { name: "finish", 
    keys: [
      { id: "oily", label: "Oily" },
      { id: "dry",  label: "Dry" },
      { id: "matte", label: "Matte" },
      { id: "natural", label: "Natural" },
      { id: "radiant", label: "Radiant / Glow" }
    ]
  },
  { name: "texture", 
    keys: [
      { id: "matte", labal: "Matte" }
    ]
  }
];

const drupal = [
  { name: "skinType", 
    keys: [
      { id: "oily", label: "Oily" },
      { id: "dry",  label: "Dry" },
      { id: "gandac", label: "mazga" }
    ]
  },
  { name: "finish", 
    keys: [
      { id: "oily", label: "Oily" }
    ]
  }
];

var result = [];
for(var item1 of react)
  for(var item2 of drupal)
    if(item1.name == item2.name){
      var keys = item2.keys.filter(x => item1.keys.some(y => y.id === x.id));
      result.push({name: item1.name, keys})      
      break;
    }  
console.log(result);


这个可以通过一个小改动来实现:将以下代码:var keys = item2.keys.filter(x => item1.keys.filter(y => y.id == x.id)[0]);替换为:var keys = item2.keys.filter(x => item1.keys.some(y => y.id === x.id)) - aircraft721

0
你关心重复吗?

const array1 = [1,2,3,4];
const array2 = [5,6,7,8];

const union = (a1, a2) => [...a1, ...a2];

console.log(union(array1, array2));

如果您不想要重复

const array1 = [1,2,3,4,5];
const array2 = [4,5,6,7,8];


const distinct = (array) =>
  array
    ? array.reduce((results, item) => {
        if (!results.some((i) => i === item)) {
          results.push(item);
        }
        return results;
      }, [])
    : array;
    
const union = (a1, a2) => distinct([...a1, ...a2]);

console.log(union(array1, array2));


OP添加了“输入”和“期望输出”。 - random
作为旁注(因为问题不是关于联合而是交集):要删除重复项,[...new Set([...arr1, ...arr2])]更短。 - connexo

0

另一种方法是通过首先将数组缩减为映射(通过key.id标准),然后通过Object.values()提取映射的值,以获取作为值数组的联合结果,从而避免联合结果中重复的值。

中间映射阶段背后的思想是确保联合结果中的值是由key.id唯一确定的。

代码解决方案可以如下所示:

const react=[{name:"skinType",keys:[{id:"oily",label:"Oily"},{id:"dry",label:"Dry"}]},{name:"finish",keys:[{id:"oily",label:"Oily"},{id:"dry",label:"Dry"},{id:"matte",label:"Matte"},{id:"natural",label:"Natural"},{id:"radiant",label:"Radiant / Glow"}]},{name:"texture",keys:[{id:"matte",labal:"Matte"}]}];const drupal=[{name:"skinType",keys:[{id:"oily",label:"Oily"},{id:"dry",label:"Dry"},{id:"gandac",label:"mazga"}]},{name:"finish",keys:[{id:"oily",label:"Oily"}]}];

/* Gather both arrays into a combined array via concat() and reduce() the result 
to obtain the union. The reduce() produces a mapping, and we obtain the union array
via Object.values() to extract the map's values as an array */
const union = Object.values([].concat(drupal, react).reduce((map, item) => {

  /* For each item of the keys sub-array, update the map with value "key" at key 
  "key.id" given that key.id is the union criteria */
  item.keys.forEach(key => {
    map[key.id] = key;
  })

  return map;
}, {}))


console.log(union);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接