繁体   English   中英

如何检查对象是否存在于多个数组中

[英]How check if object exists in multiple arrays

首先,感谢您阅读我的问题,并尝试帮助我并为我的英语道歉。

我的问题是我想实现一个不错的解决方案,在数组中使用更少的数组。

我有n个带有n个对象的数组,每个对象都有两个属性:name和type。 我想知道如何重复获取所有数组中的对象。

这是我的代码:

let arraysNoEmpties = [...res].filter(array => array.length > 0);
let attributes = arraysNoEmpties[0].map(p => {
   return { name: p.name, type: p.type };
});

let items = getAtributeInAllArrays(attributes, arraysNoEmpties);
console.log('items: ', items);


const getAtributeInAllArrays = (properties, list) => {
    let items = [];
    for (let i = 0; i < properties.length; i++) {
        const property = properties[i];
        let numTimes = 0;
        for (let j = 0; j< list.length; j++) {
            const array = list[j];
            let propsOfarray = array.map(atr => atr.name);
            if (propsOfarray.indexOf(property.name) !== -1) {
                numTimes++;
                if (numTimes === list.length) {
                    items.push(property);
                }
            }
        }
    }
    items.sort((a,b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
    return items;
};

您要过滤在提供的每个数组中找不到的每个对象。 我们可以利用一些函数来实现此目的:

let arrays = [[{name:"1"}, {name:"2"}], [{name:"1"}]]
let objects = [{name:"1"}, {name:"2"}] // only the first object is found in each array
const objectsInEachArray = objects.filter(o => arrays.every(arr => arr.some(r => r.name == o.name && r.type == o.type)))

让我们刹车一下:

  1. 要检查对象是否包含在数组中,我们可以使用array.some()函数。 在这里,我们返回一个布尔值以声明是否匹配。 在这种情况下,我想您想检查每个属性。 在这里,您可以进行完全相等性检查(深层或浅层),或者在这种简单情况下,只需显式检查每个属性即可:

     arr.some(r => r.name == o.name && r.type == o.type) 
  2. 由于我们有多个数组,并且要求在每个对象中至少找到一个对象,因此必须在2维数组上调用every方法:

     arrays.every(arr => arr.some(r => r.name == o.name && r.type == o.type)))) 
  3. 因为我们有多个对象,并且希望结果是一个只有匹配对象的数组,所以我们在对象数组上调用filter。

     objects.filter(o => arrays.every(arr => arr.some(r => r.name == o.name && r.type == o.type))))) 

    objectsInEachArray现在仅包含在每个第二级阵列发现从对象arrays

因此:

console.log(objectsInEachArray) -> [{name: "1"}]

如果数组的长度相似或全部很小(<〜20个元素),则可以使用类似的方法。 修改predicate函数以指定两个对象匹配的条件。 例如,如果添加另一个元素或确定name即使没有type也是唯一的。

function commonElements(arrays...) {
  const predicate = (obj1, obj2) => {
    return obj1.name == obj2.name && obj1.type == obj2.type;
  };

  return arrays[0].filter(e1 => !arrays.map(array => array.map(e2 => predicate(e1, e2)).includes(true)).includes(false));
}

如果您可能有一些较长的数组,请首先选择最短的数组作为过滤器的基础:

function commonElements(arrays...) {
  const predicate = (obj1, obj2) => {
    return obj1.name == obj2.name && obj1.type == obj2.type;
  };

  const lengths = arrays.map(arr => arr.length);
  const shortestArray = arrays[lengths.indexOf(lengths.sort((a, b) => a - b)[0])];

  return shortestArray.filter(e1 => !arrays.map(array => array.map(e2 => predicate(e1, e2)).includes(true)).includes(false));
}

这两个示例的最后一行基本上是相同的,并且形式稍长一些:

shortestArray.filter(e1 => {
  return !arrays.map(array => {
    return array.map(e2 => {
      return predicate(e1, e2);
    }).includes(true);
  }).includes(false);
});

对于过滤器数组的每个元素,使用predicate函数将其与其他数组中的每个元素进行比较。 如果至少一个元素匹配( .includes(true) ),则将该数组映射为true 如果每个数组都映射为true! (...) .includes(false) ),则该元素将被.filter(...)接受。

暂无
暂无

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

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