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

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"}

当前回答

这种方式对我很有效:

function arrayUnique(arr, uniqueKey) {
  const flagList = new Set()
  return arr.filter(function(item) {
    if (!flagList.has(item[uniqueKey])) {
      flagList.add(item[uniqueKey])
      return true
    }
  })
}
const data = [
  {
    name: 'Kyle',
    occupation: 'Fashion Designer'
  },
  {
    name: 'Kyle',
    occupation: 'Fashion Designer'
  },
  {
    name: 'Emily',
    occupation: 'Web Designer'
  },
  {
    name: 'Melissa',
    occupation: 'Fashion Designer'
  },
  {
    name: 'Tom',
    occupation: 'Web Developer'
  },
  {
    name: 'Tom',
    occupation: 'Web Developer'
  }
]
console.table(arrayUnique(data, 'name'))// work well

打印输出

┌─────────┬───────────┬────────────────────┐
│ (index) │   name    │     occupation     │
├─────────┼───────────┼────────────────────┤
│    0    │  'Kyle'   │ 'Fashion Designer' │
│    1    │  'Emily'  │   'Web Designer'   │
│    2    │ 'Melissa' │ 'Fashion Designer' │
│    3    │   'Tom'   │  'Web Developer'   │
└─────────┴───────────┴────────────────────┘

ES5:

function arrayUnique(arr, uniqueKey) {
  const flagList = []
  return arr.filter(function(item) {
    if (flagList.indexOf(item[uniqueKey]) === -1) {
      flagList.push(item[uniqueKey])
      return true
    }
  })
}

这两种方式更简单易懂。

其他回答

const objectsMap = new Map();
const placesName = [
  { place: "here", name: "stuff" },
  { place: "there", name: "morestuff" },
  { place: "there", name: "morestuff" },
];
placesName.forEach((object) => {
  objectsMap.set(object.place, object);
});
console.log(objectsMap);

TypeScript解决方案

这将删除重复的对象,并保留对象的类型。

function removeDuplicateObjects(array: any[]) {
  return [...new Set(array.map(s => JSON.stringify(s)))]
    .map(s => JSON.parse(s));
}
    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);

removeDucplicates()接受一个对象数组,并返回一个没有任何重复对象的新数组(基于id属性)。

const allTests = [
  {name: 'Test1', id: '1'}, 
  {name: 'Test3', id: '3'},
  {name: 'Test2', id: '2'},
  {name: 'Test2', id: '2'},
  {name: 'Test3', id: '3'}
];

function removeDuplicates(array) {
  let uniq = {};
  return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true))
}

removeDuplicates(allTests);

预期结果:

[
  {name: 'Test1', id: '1'}, 
  {name: 'Test3', id: '3'},
  {name: 'Test2', id: '2'}
];

首先,我们将变量uniq的值设置为空对象。

接下来,我们过滤对象数组。Filter创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));

上面,我们使用了&&的短路功能。如果&&的左侧求值为true,则返回&&右侧的值。如果左侧为false,则返回&&左侧的内容。

对于每个对象(obj),我们检查uniq中名为obj.id值的属性(在这种情况下,在第一次迭代时,它将检查属性“1”。)我们希望它返回的结果(true或false)相反,这就是为什么我们使用!在里面uniq[obj.id]。如果uniq已经具有id属性,则返回true,其计算结果为false(!),告诉过滤函数不要添加该obj。但是,如果未找到obj.id属性,它返回false,然后计算结果为true(!)并返回&&或(uniq[obj.id]=true)右侧的所有内容。这是一个truthy值,告诉filter方法将该obj添加到返回的数组中,并且还将属性{1:true}添加到uniq中。这确保不会再添加具有相同id的任何其他obj实例。

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

您将拥有这一行:

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