我有一个包含对象数组的对象。

obj = {};

obj.arr = new Array();

obj.arr.push({place:"here",name:"stuff"});
obj.arr.push({place:"there",name:"morestuff"});
obj.arr.push({place:"there",name:"morestuff"});

我想知道从数组中删除重复对象的最佳方法是什么。例如,obj.arr将变成。。。

{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}

当前回答

如果您发现需要经常基于特定字段从数组中删除重复的对象,那么创建一个可以从项目中任何位置导入的独特(数组、谓词)函数可能是值得的。这看起来像

const things = [{place:"here",name:"stuff"}, ...];
const distinctThings = distinct(things, thing => thing.place);

不同的函数可以使用上面许多好答案中给出的任何实现。最简单的方法是使用findIndex:

const distinct = (items, predicate) => items.filter((uniqueItem, index) =>
    items.findIndex(item =>
        predicate(item) === predicate(uniqueItem)) === index);

其他回答

如果您希望基于所有参数而不仅仅是一个参数来消除数组的重复。可以使用lodash的uniqBy函数,该函数可以将函数作为第二个参数。

您将拥有这一行:

 _.uniqBy(array, e => { return e.place && e.name })

让myData=[{place:“here”,name:“stuff”},{地点:“there”,名称:“morestuff”},{地点:“there”,名称:“morestuff”}];let q=[…new Map(myData.Map(obj=>[JSON.stringify(obj),obj]).values()];控制台日志(q)

一个使用ES6和new Map()的命令行。

// assign things.thing to myData
let myData = things.thing;

[...new Map(myData.map(obj => [JSON.stringify(obj), obj])).values()];

详细信息:-

对数据列表执行.map()并将每个单独的对象转换为[key,value]对数组(长度=2),第一个元素(key)将是对象的字符串化版本,第二个元素(value)将是一个对象本身。将上述创建的数组列表添加到新的Map()中会将键作为字符串化对象,任何相同的键添加都会导致覆盖现有的键。使用.values()将为MapIterator提供Map中的所有值(在本例中为obj)最后,传播。。。运算符为新数组提供上述步骤中的值。

这个问题可以简化为从对象数组中删除重复项。

您可以通过使用一个对象来维护作为键的唯一条件并存储相关值来实现更快的O(n)解决方案(假设本机键查找可以忽略不计)。

基本上,这个想法是用唯一的键存储所有对象,这样重复的对象就会覆盖自己:

const thing=[{地点:“这里”,名称:“stuff”},{地点“那里”,名称“morestuff”},{地方:“那里”、名称:“morestuff]常量uniques={}用于(事物的常量){const key=t.place+'$'+t.name//或您想要的任何字符串条件,可以将其生成为Object.keys(t).join(“$”)uniques[key]=t//上次重复获胜}constuniqueThing=对象.values(uniques)console.log(uniqueThing)

为懒惰的Typescript开发人员提供快速(运行时更少)和类型安全的答案:

export const uniqueBy = <T>( uniqueKey: keyof T, objects: T[]): T[] => {
  const ids = objects.map(object => object[uniqueKey]);
  return objects.filter((object, index) => !ids.includes(object[uniqueKey], index + 1));
} 
    function genFilterData(arr, key, key1) {
      let data = [];
      data = [...new Map(arr.map((x) => [x[key] || x[key1], x])).values()];
    
      const makeData = [];
      for (let i = 0; i < data.length; i += 1) {
        makeData.push({ [key]: data[i][key], [key1]: data[i][key1] });
      }
    
      return makeData;
    }
    const arr = [
    {make: "here1", makeText:'hj',k:9,l:99},
    {make: "here", makeText:'hj',k:9,l:9},
    {make: "here", makeText:'hj',k:9,l:9}]

      const finalData= genFilterData(data, 'Make', 'MakeText');
    
        console.log(finalData);