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

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

当前回答

这里有一个使用JavaScript新过滤功能的解决方案,非常简单。假设你有一个这样的数组。

var duplicatesArray = ['AKASH','AKASH','NAVIN','HARISH','NAVIN','HARISH','AKASH','MANJULIKA','AKASH','TAPASWENI','MANJULIKA','HARISH','TAPASWENI','AKASH','MANISH','HARISH','TAPASWENI','MANJULIKA','MANISH'];

filter函数将允许您为数组中的每个元素使用一次回调函数来创建一个新数组。所以你可以这样设置唯一的数组。

var uniqueArray = duplicatesArray.filter(function(elem, pos) {return duplicatesArray.indexOf(elem) == pos;});

在这种情况下,您的唯一数组将遍历重复数组中的所有值。elem变量表示数组中元素的值(mike、james、james和alex),位置是它在数组中的0索引位置(0,1,2,3…),duplicatesArray.indexOf(elem)值只是该元素在原始数组中第一次出现的索引。因此,因为元素'james'是重复的,所以当我们循环遍历duplicatesArray中的所有元素并将它们推送到uniqueArray时,第一次命中james时,我们的“pos”值为1,indexOf(elem)也为1,因此james被推送到unique Array。第二次命中James时,我们的“pos”值为2,indexOf(elem)仍然为1(因为它只找到数组元素的第一个实例),因此不会推送重复项。因此,uniqueArray只包含唯一值。

这是上述功能的演示。单击此处查看上述功能示例

其他回答

您也可以使用地图:

const dedupThings = Array.from(things.thing.reduce((m, t) => m.set(t.place, t), new Map()).values());

完整样本:

const things = new Object();

things.thing = new Array();

things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});

const dedupThings = Array.from(things.thing.reduce((m, t) => m.set(t.place, t), new Map()).values());

console.log(JSON.stringify(dedupThings, null, 4));

结果:

[
    {
        "place": "here",
        "name": "stuff"
    },
    {
        "place": "there",
        "name": "morestuff"
    }
]

您还可以创建一个通用函数,该函数将根据传递给该函数的对象键过滤数组

function getUnique(arr, comp) {

  return arr
   .map(e => e[comp])
   .map((e, i, final) => final.indexOf(e) === i && i)  // store the keys of the unique objects
   .filter(e => arr[e]).map(e => arr[e]); // eliminate the dead keys & store unique objects

 }

你可以这样调用函数,

getUnique(things.thing,'name') // to filter on basis of name

getUnique(things.thing,'place') // to filter on basis of place

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

在数组中查找唯一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)

如果您正在使用Lodash库,也可以使用以下函数。它应该删除重复的对象。

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);

如果您严格希望基于一个属性删除重复项,则可以基于place属性将数组缩减为和对象,因为对象只能具有唯一的键,因此只需获取值即可返回数组:

const unique = Object.values(things.thing.reduce((o, t) => ({ ...o, [t.place]: t }), {}))