我有一个包含对象数组的对象。
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"}
我知道这个问题已经有很多答案了,但请耐心等待。。。
数组中的某些对象可能具有您不感兴趣的其他财产,或者您只想查找只考虑财产子集的唯一对象。
考虑下面的数组。假设您想仅考虑propOne和propTwo来查找此数组中的唯一对象,而忽略可能存在的任何其他财产。
预期结果应仅包括第一个和最后一个对象。代码如下:
常量数组=[{propOne:“a”,propTwo:“b”,第三题:“我没有参与……”},{propOne:“a”,propTwo:“b”,someOtherProperty:“没有人关心这个…”},{propOne:'x',propTwo:'y',yetAotherJunk:“我真的一文不值”,这个:“我有一些别人没有的东西”}];常量uniques=[…新集合(array.map(x=>JSON.stringify(((o)=>({propOne:o.propOne,propTwo:o.propTwo}))(x) ))].map(JSON.parse);console.log(uniques);
考虑lodash.uniqWith
const objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
这是一种通用的方法:传入一个函数,该函数测试数组的两个元素是否相等。在本例中,它比较所比较的两个对象的名称和位置财产的值。
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);
如果您可以等到所有添加之后再消除重复项,典型的方法是首先对数组进行排序,然后消除重复项。排序避免了在遍历每个元素时扫描数组的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;
}