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

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

这两种方式更简单易懂。

其他回答

简单高效的解决方案,运行时间比现有的70多个答案更好:

const ids = array.map(o => o.id)
const filtered = array.filter(({id}, index) => !ids.includes(id, index + 1))

例子:

const arr=[{id:1,名称:“one”},{id:2,名称:‘two’},{id:1,姓名:‘one’}]常量id=arr.map(o=>o.id)constfiltered=arr.filter(({id},索引)=>!ids.includes(id,索引+1))console.log(已过滤)

工作原理:

Array.filter()通过检查先前映射的id数组是否包含当前id来删除所有重复的对象({id}仅将对象销毁为其id)。为了只过滤出实际的重复项,它使用了Array.includes()的第二个参数fromIndex,索引为+1,这将忽略当前对象和所有先前对象。

由于过滤器回调方法的每一次迭代都将只搜索从当前索引+1开始的数组,这也大大减少了运行时间,因为只有以前未过滤的对象才会被检查。

这显然也适用于任何其他不称为id的键、多个键甚至所有键。

如果需要基于对象中的多个财产的唯一数组,可以通过映射和组合对象的财产来实现。

    var hash = array.map(function(element){
        var string = ''
        for (var key in element){
            string += element[key]
        }
        return string
    })
    array = array.filter(function(element, index){
        var string = ''
        for (var key in element){
            string += element[key]
        }
        return hash.indexOf(string) == index
    })

使用Set的一个衬垫

var things=新对象();things.thing=新数组();thing.thing.push({place:“here”,name:“stuff”});things.thing.push({place:“there”,name:“morestuff”});things.thing.push({place:“there”,name:“morestuff”});//为简洁起见,将things.thing分配给myDatavar myData=things.thing;things.thing=数组.from(新集合(myData.map(JSON.stringify))).map(JSON解析);console.log(things.thing)

说明:

newSet(myData.map(JSON.stringify))使用字符串化的myData元素创建一个Set对象。Set对象将确保每个元素都是唯一的。然后,我使用array.from基于创建的集合的元素创建一个数组。最后,我使用JSON.parse将字符串化元素转换回对象。

TypeScript函数将数组过滤到其唯一元素,其中唯一性由给定的谓词函数决定:

function uniqueByPredicate<T>(arr: T[], predicate: (a: T, b: T) => boolean): T[] {
  return arr.filter((v1, i, a) => a.findIndex(v2 => predicate(v1, v2)) === i);
}

不打字员:

function uniqueByPredicate(arr, predicate) {
  return l.filter((v1, i, a) => a.findIndex(v2 => predicate(v1, v2)) === i);
}

可以使用for循环和条件使其唯一

const data = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 6 },
{ id: 6 },
{ id: 7 },
{ id: 8 },
{ id: 8 },
{ id: 8 },
{ id: 8 }
];

const filtered= []

for(let i=0; i<data.length; i++ ){
    let isHasNotEqual = true
    for(let j=0; j<filtered.length; j++ ){
      if (filtered[j].id===data[i].id){
          isHasNotEqual=false
      }
    }
    if (isHasNotEqual){
        filtered.push(data[i])
    }
}
console.log(filtered);

/*
output
[ { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4 },
  { id: 5 },
  { id: 6 },
  { id: 7 },
  { id: 8 } ]

*/