【问题标题】:Filter out an array from the duplicates in another array从另一个数组中的重复项中过滤掉一个数组
【发布时间】:2019-09-17 15:57:21
【问题描述】:

给定这两个数组:

const array1 = [
                {"id": 1, "color": "black"},
                {"id": 2, "color": "white"},
                {"id": 3, "color": "orange"}
               ];

const array2 = [
                {"id": 2, "color": "white"},
                {"id": 4, "color": "purple"}
               ];

如果在第二个数组中找到重复项,我如何从第一个数组中删除重复项,即结果将是:

const filtered = [
                  {"id": 1, "color": "black"},
                  {"id": 3, "color": "orange"}
                 ];

我的代码:

const filtered = array1.map(i => array2.filter(j => i["id"] !== j["id"]))

但它似乎不起作用

【问题讨论】:

  • id 属性或属性组合是否考虑了重复项?例如,如果array2 包含{ "id": 3, "color": "blue" },您的预期行为是什么
  • @AndrewLohr 相关,但不完全相同。我确定有一个,但那个答案依赖于按值比较数组元素的能力(而不是每个元素的属性)。

标签: javascript arrays ecmascript-6


【解决方案1】:

要使您的代码正常工作,您可以使用过滤器和每个

const array1 = [ {"id": 1, "color": "black"},{"id": 2, "color": "white"},{"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"},{"id": 4, "color": "purple"}];

const filtered = array1.filter(i => array2.every(j => i["id"] !== j["id"]))

console.log(filtered)

您可以使用地图和过滤器

const array1 = [ {"id": 1, "color": "black"},{"id": 2, "color": "white"},{"id": 3, "color": "orange"}];
const array2 = [{"id": 2, "color": "white"},{"id": 4, "color": "purple"}];

let mapper = new Map(array2.map(v=> [v.id,v]))

const final = array1.filter(({id})=> !mapper.has(id))

console.log(final)

【讨论】:

    【解决方案2】:

    如果您希望仅根据“id”删除重复项,您可以使用Array.filter()Array.find()Array.some() 执行此操作 -

    const filtered = array1.filter(x => !array2.find( y => y.id===x.id));
    

    const filtered = array1.filter(x => !array2.some( y => y.id===x.id));
    

    检查this JS Bin 玩。

    【讨论】:

      【解决方案3】:

      我们可以使用Array.prototype.filter 过滤第一个数组。过滤条件可以通过具有不同时间复杂度的多种方式构建:

      1. 使用Array.prototype.findIndex 的线性时间将检查当前对象是否包含在第二个数组中:

      const array1 = [{"id": 1, "color": "black"}, {"id": 2, "color": "white"}, {"id": 3, "color": "orange"}];
      const array2 = [{"id": 2, "color": "white"}, {"id": 4, "color": "purple"}];
      
      function filterArray(array1, array2,){
        return array1.filter( ({id}) => array2.findIndex((o) => id === o.id ) < 0);
      }
      console.log(filterArray(array1, array2));
      1. 或者这也可以通过使用具有恒定时间查找的Set 来有效地完成:

      const array1 = [{"id": 1, "color": "black"}, {"id": 2, "color": "white"}, {"id": 3, "color": "orange"}];
      const array2 = [{"id": 2, "color": "white"}, {"id": 4, "color": "purple"}];
      
      function filterArrayUsingSet(array1, array2){
        const lookup = new Set(array2.map(({id})  => id));
        return array1.filter( ({id}) => !lookup.has(id) );
      }
      
      console.log(filterArrayUsingSet(array1, array2));
      1. 即使是 Object 字面量也可以用作键查找表,其中键是 array2ids,这也是常量时间查找:

      const array1 = [{"id": 1, "color": "black"}, {"id": 2, "color": "white"}, {"id": 3, "color": "orange"}];
      const array2 = [{"id": 2, "color": "white"}, {"id": 4, "color": "purple"}];
      
      function filterArrayUsingSet(array1, array2){
        const lookup = array2.reduce((acc, {id}) => {acc[id] = id; return acc}, {});
        return array1.filter( ({id}) => !(id in lookup));
      }
      
      console.log(filterArrayUsingSet(array1, array2));

      【讨论】:

        【解决方案4】:

        如果要根据在第二个数组中找到的任何键值匹配来过滤数组,使用 forEach 和 every 的解决方案:

        function filterArray(arr1, arr2) {
            let filterArr = [];
            arr1.forEach(item => 
               arr2.every( val => val.id !== item.id && val.color !== item.color) && filterArr.push(item));
        
            return filterArr;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-16
          • 1970-01-01
          • 1970-01-01
          • 2023-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多