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

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

当前回答

可以使用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 } ]

*/








其他回答

我认为,将reduce与JSON.stringify结合起来以完美地比较对象,并选择性地添加那些尚未在累加器中的对象是一种优雅的方式。

请记住,在极端情况下,JSON.stringify可能会成为一个性能问题,因为阵列有许多对象,而且它们很复杂,但在大多数情况下,这是IMHO的最短路径。

var集合=〔{a:1},{a:2},{a:1},{a:3}〕var filtered=collection.reduce((已过滤,项)=>{if(!filtered.some(filteredItem=>JSON.stringify(filtered item)==JSON.sstringify(item)))已过滤推送(项)返回已过滤}, [])console.log(已过滤)

另一种写法相同(但效率较低):

collection.reduce((filtered, item) => 
  filtered.some(filteredItem => 
    JSON.stringify(filteredItem ) == JSON.stringify(item)) 
      ? filtered
      : [...filtered, item]
, [])

如果您可以等到所有添加之后再消除重复项,典型的方法是首先对数组进行排序,然后消除重复项。排序避免了在遍历每个元素时扫描数组的N*N方法。

“消除重复项”函数通常称为unique或uniq。一些现有的实现可以结合这两个步骤,例如原型的uniq

如果你的图书馆还没有,这篇文章没有什么想法可以尝试(还有一些需要避免:-)!我个人认为这是最直接的:

    function unique(a){
        a.sort();
        for(var i = 1; i < a.length; ){
            if(a[i-1] == a[i]){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }  

    // Provide your own comparison
    function unique(a, compareFunc){
        a.sort( compareFunc );
        for(var i = 1; i < a.length; ){
            if( compareFunc(a[i-1], a[i]) === 0){
                a.splice(i, 1);
            } else {
                i++;
            }
        }
        return a;
    }

任何对象数组的泛型:

/**
* Remove duplicated values without losing information
*/
const removeValues = (items, key) => {
  let tmp = {};

  items.forEach(item => {
    tmp[item[key]] = (!tmp[item[key]]) ? item : Object.assign(tmp[item[key]], item);
  });
  items = [];
  Object.keys(tmp).forEach(key => items.push(tmp[key]));

  return items;
}

希望这对任何人都有帮助。

这里是ES6的解决方案,您只想保留最后一项。该解决方案功能强大,符合Airbnb风格。

const things = {
  thing: [
    { place: 'here', name: 'stuff' },
    { place: 'there', name: 'morestuff1' },
    { place: 'there', name: 'morestuff2' }, 
  ],
};

const removeDuplicates = (array, key) => {
  return array.reduce((arr, item) => {
    const removed = arr.filter(i => i[key] !== item[key]);
    return [...removed, item];
  }, []);
};

console.log(removeDuplicates(things.thing, 'place'));
// > [{ place: 'here', name: 'stuff' }, { place: 'there', name: 'morestuff2' }]

这是一种通用的方法:传入一个函数,该函数测试数组的两个元素是否相等。在本例中,它比较所比较的两个对象的名称和位置财产的值。

ES5答案

函数removeDucplicates(arr,equals){var originalArr=arr.slice(0);变量i,len,val;arr.length=0;对于(i=0,len=原始Arr.length;i<len;++i){val=原始Arr[i];if(!arr.some(函数(项){return equals(项,val);})){arr.push(val);}}}函数thingsEqual(thing1,thing2){返回thing1.place==thing2.place&&thing.name===thing.name;}var事物=[{地点:“这里”,名称:“东西”},{地点:“there”,名称:“morestuff”},{地点:“there”,名称:“morestuff”}];删除重复项(things,thingsEqual);console.log(things);

ES3原始答案

function arrayContains(arr, val, equals) {
    var i = arr.length;
    while (i--) {
        if ( equals(arr[i], val) ) {
            return true;
        }
    }
    return false;
}

function removeDuplicates(arr, equals) {
    var originalArr = arr.slice(0);
    var i, len, j, val;
    arr.length = 0;

    for (i = 0, len = originalArr.length; i < len; ++i) {
        val = originalArr[i];
        if (!arrayContains(arr, val, equals)) {
            arr.push(val);
        }
    }
}

function thingsEqual(thing1, thing2) {
    return thing1.place === thing2.place
        && thing1.name === thing2.name;
}

removeDuplicates(things.thing, thingsEqual);