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

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 removeDuplicates(myArr) {
  var props = Object.keys(myArr[0])
  return myArr.filter((item, index, self) =>
    index === self.findIndex((t) => (
      props.every(prop => {
        return t[prop] === item[prop]
      })
    ))
  )
}

再见!与IE11不兼容。

其他回答

带有Map的一行程序(高性能,不保留顺序)

在数组arr中查找唯一id。

const arrUniq = [...new Map(arr.map(v => [v.id, v])).values()]

如果订单很重要,请检查带过滤器的解决方案:带过滤器的方案


由数组arr中的多个财产(位置和名称)唯一

const arrUniq = [...new Map(arr.map(v => [JSON.stringify([v.place,v.name]), v])).values()]

由数组arr中的所有财产唯一

const arrUniq = [...new Map(arr.map(v => [JSON.stringify(v), v])).values()]

保留数组arr中的第一次出现

const arrUniq = [...new Map(arr.slice().reverse().map(v => [v.id, v])).values()].reverse()

对于一个可读且简单的解决方案搜索者,她是我的版本:

    function removeDupplicationsFromArrayByProp(originalArray, prop) {
        let results = {};
        for(let i=0; i<originalArray.length;i++){
            results[originalArray[i][prop]] = originalArray[i];
        }
        return Object.values(results);
    }

这是一种带有Set和一些闭包的单循环方法,以防止在函数声明之外使用声明的变量,并获得简短的外观。

常量array=[{地点:“here”,名称:“stuff”,n:1},{地方:“there”,名称“morestuff”,keys=['place','name'],unique=阵列过滤器((s=>o=>(v=>!s.has(v)&&s.add(v))(keys.map(k=>o[k]).join('|')))(新设置));console.log(唯一);.作为控制台包装{最大高度:100%!重要;顶部:0;}

这种方式对我很有效:

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的键、多个键甚至所有键。