根据一个属性的唯一性过滤数组对象

时间:2019-11-22 19:17:12

标签: javascript arrays reactjs

我要处理的情况是我有一个对象数组,并且我想过滤到一个数组,在该数组中,对于保留最后一个实例的一个属性,对象是唯一的。

例如,假设我有一个像这样的文件数组:

let files = 
     [
        {
          filename: "filename.txt",
          uploadedBy: "Bob",
          comment: "Gee whiz"
        },
          filename: "filename.txt",
          uploadedBy: "Jane",
          comment: "Golly"
        },
          filename: "otherFile.txt",
          uploadedBy: "Bob",
          comment: "Shucks"
        },
          filename: "filename.txt",
          uploadedBy: "Henry",
          comment: "Gee Willikers"
        },
     ]

我想要具有不同文件名的对象,并且想要每个文件名的最后一个实例。

     [
          filename: "otherFile.txt",
          uploadedBy: "Bob",
          comment: "Shucks"
        },
          filename: "filename.txt",
          uploadedBy: "Henry",
          comment: "Gee Willikers"
        },
     ]

是否有一种简洁的方法?我所能想到的是一个相当长的方法,它首先map数组仅获取文件名,然后找到每个文件名或某些内容的最后一个实例。

以下问题类似,但保留第一个值而不是最后一个值: Get all unique values in a JavaScript array (remove duplicates)

 function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}

// usage example:
var a = ['a', 1, 'a', 2, '1'];
var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

3 个答案:

答案 0 :(得分:0)

您可以首先从数组中获取唯一的文件名,然后只需在它们上映射并在反向文件数组中查找第一个元素。

const f = [{"filename":"filename.txt","uploadedBy":"Bob","comment":"Gee whiz"},{"filename":"filename.txt","uploadedBy":"Jane","comment":"Golly"},{"filename":"otherFile.txt","uploadedBy":"Bob","comment":"Shucks"},{"filename":"filename.txt","uploadedBy":"Henry","comment":"Gee Willikers"}].reverse();

const unique = [...new Set(f.map(({ filename }) => filename))]
         .map((name) => f.find(({ filename }) => filename === name)); 

console.log(unique);

答案 1 :(得分:0)

简化为地图,并使用filename作为设置项目的键,然后将Map.values()迭代器散布回数组:

const files = [{"filename":"filename.txt","uploadedBy":"Bob","comment":"Gee whiz"},{"filename":"filename.txt","uploadedBy":"Jane","comment":"Golly"},{"filename":"otherFile.txt","uploadedBy":"Bob","comment":"Shucks"},{"filename":"filename.txt","uploadedBy":"Henry","comment":"Gee Willikers"}]

const result = [...
  files.reduce((m, o) => m.set(o.filename, o), new Map())
.values()]

console.log(result)

答案 2 :(得分:0)

您可以使用Map,其中每个filename都是唯一的,文件对象是值。如果找到另一个具有相同filename的条目,它将覆盖先前的值。因此,它将始终是最后一次出现。然后将地图的values放到文件对象中

const files=[{filename:"filename.txt",uploadedBy:"Bob",comment:"Gee whiz"},{filename:"filename.txt",uploadedBy:"Jane",comment:"Golly"},{filename:"otherFile.txt",uploadedBy:"Bob",comment:"Shucks"},{filename:"filename.txt",uploadedBy:"Henry",comment:"Gee Willikers"},];

const map = new Map(files.map(f => [f.filename, f])),
      unique = Array.from(map.values());
      
console.log(unique)