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

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

当前回答

TypeScript解决方案

这将删除重复的对象,并保留对象的类型。

function removeDuplicateObjects(array: any[]) {
  return [...new Set(array.map(s => JSON.stringify(s)))]
    .map(s => JSON.parse(s));
}

其他回答

在一行中使用ES6+,您可以按键获得唯一的对象列表:

const key = 'place';
const unique = [...new Map(arr.map(item => [item[key], item])).values()]

可以将其放入函数中:

function getUniqueListBy(arr, key) {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}

下面是一个工作示例:

常量arr=[{地点:“这里”,名称:“x”,其他:“其他stuff1”},{地点:“那里”,名称:“x”,其他:“其他stuff2”},{地点:“这里”,名称:“y”,其他:“其他stuff4”},{地点:“这里”,名称:“z”,其他:“其他stuff5”}]函数getUniqueListBy(arr,key){return[…new Map(arr.Map(item=>[item[key],item])).values()]}const arr1=getUniqueListBy(arr,'place')console.log(“按位置唯一”)console.log(JSON.stringify(arr1))console.log(“\n名称唯一”)const arr2=getUniqueListBy(arr,'name')console.log(JSON.stringify(arr2))

它是如何工作的

首先,以可以用作Map输入的方式重新映射数组。

arr.map(项=>[项[键],项]);

这意味着阵列的每个项目将被转换为具有2个元素的另一个阵列;选定的键作为第一个元素,整个初始项作为第二个元素,这称为条目(例如数组条目、映射条目)。这是一个官方文档,其中有一个示例显示了如何在Map构造函数中添加数组项。

放置钥匙时的示例:

[["here", {place: "here",  name: "x", other: "other stuff1" }], ...]

其次,我们将这个修改后的数组传递给Map构造函数,这就是神奇的发生。映射将消除重复的关键字值,只保留同一关键字的最后插入值。注意:贴图保持插入顺序。(检查贴图和对象之间的差异)

新映射(上面刚刚映射的条目数组)

第三,我们使用map值来检索原始项,但这次没有重复项。

新映射(mappedArr).values()

最后一个是将这些值添加到一个新的数组中,这样它可以看起来像初始结构,并返回:

return[…new Map(mappedArr).values()]

您也可以使用地图:

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

这是如何从对象数组中删除重复性的简单方法。

我经常处理数据,这对我很有用。

const data = [{name: 'AAA'}, {name: 'AAA'}, {name: 'BBB'}, {name: 'AAA'}];
function removeDuplicity(datas){
    return datas.filter((item, index,arr)=>{
    const c = arr.map(item=> item.name);
    return  index === c.indexOf(item.name)
  })
}

console.log(removeDuplicity(data))

将打印到控制台:

[[object Object] {
name: "AAA"
}, [object Object] {
name: "BBB"
}]

es6魔术在一条线上。。。在那时候可读!

// returns the union of two arrays where duplicate objects with the same 'prop' are removed
const removeDuplicatesWith = (a, b, prop) => {
  a.filter(x => !b.find(y => x[prop] === y[prop]));
};

另一种方法是使用reduce函数,并使用一个新数组作为累加器。如果累加器数组中已经有一个同名的对象,那么不要将其添加到那里。

let list = things.thing;
list = list.reduce((accumulator, thing) => {
    if (!accumulator.filter((duplicate) => thing.name === duplicate.name)[0]) {
        accumulator.push(thing);
    }
    return accumulator;
}, []);
thing.things = list;

我添加了这个答案,因为我找不到与InternetExplorer11兼容的好的、可读的es6解决方案(我使用babel来处理箭头函数)。问题是IE11没有没有polyfill的Map.values()或Set.values)。出于同样的原因,我使用filter()[0]来获取第一个元素,而不是find()。