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

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

当前回答

这是我的两分钱。如果您知道财产的顺序相同,则可以将元素串接起来,并从数组中删除重复项,然后再次解析数组。类似于:

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”});let-stringified=things.thing.map(i=>JSON.sringify(i));let unique=stringified.filter((k,idx)=>stringified.indexOf(k)==idx).map(j=>JSON.parse(j))console.log(唯一);

其他回答

如果您可以使用诸如下划线或lodash之类的Javascript库,我建议查看它们库中的_.uniq函数。来自lodash:

_.uniq(array, [isSorted=false], [callback=_.identity], [thisArg])

基本上,您传入数组,这里是一个对象文本,然后传入要在原始数据数组中删除重复项的属性,如下所示:

var data = [{'name': 'Amir', 'surname': 'Rahnama'}, {'name': 'Amir', 'surname': 'Stevens'}];
var non_duplidated_data = _.uniq(data, 'name'); 

更新:Lodash现在也引入了.uniqBy。

带过滤器的内衬(保留订单)

在数组中查找唯一id。

arr.filter((v,i,a)=>a.findIndex(v2=>(v2.id===v.id))===i)

如果顺序不重要,映射解决方案将更快:使用映射解决方案


多个财产独有(地点和名称)

arr.filter((v,i,a)=>a.findIndex(v2=>['place','name'].every(k=>v2[k] ===v[k]))===i)

所有财产都是唯一的(对于大型阵列来说,这将很慢)

arr.filter((v,i,a)=>a.findIndex(v2=>(JSON.stringify(v2) === JSON.stringify(v)))===i)

通过用findLastIndex替换findIndex来保留最后一次出现。

arr.filter((v,i,a)=>a.findLastIndex(v2=>(v2.place === v.place))===i)

此解决方案适用于任何类型的对象,并检查数组中的每个对象(键、值)。使用临时对象作为哈希表,以查看整个object是否作为键存在。如果找到了Object的字符串表示形式,则该项将从数组中删除。

var arrOfDup=[{'id':123,'name':'name','desc':'some desc'},{“id”:125,“name”:“other name”,“desc”:“Other desc”},{“id”:123,“name”:“name”,“desc”:“some desc”},{“id”:125,“name”:“other name”,“desc”:“Other desc”},{“id”:125,“name”:“other name”,“desc”:“Other desc”}];函数removeDupes(dupArray){让temp={};let tempArray=JSON.parse(JSON.stringify(dupArray));dupArray.forEach((项,位置)=>{if(temp[JSON.stringify(item)]){tempArray.pop();}其他{temp[JSON.stringify(item)]=项;}});返回tempArray;}arrOfDup=removeDupes(arrOfDup);arrOfDup.forEach((项目,位置)=>{console.log(`${pos}位置的数组中的项是${JSON.stringify(项)}`);});

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

Dang,孩子们,让我们把这件事搞砸,为什么不呢?

让uniqIds={},source=〔{id:‘a’},{id:'b‘},{id:'c‘}、{id:s'b‘},{id:‘a‘};let filtered=source.filter(obj=>!uniqIds[obj.id]&&(uniqIds[obj.id]=true));console.log(已过滤);//预期:[{id:'a'},{id:'b'};