我似乎只能找到使用其他JS库从数组中删除重复项的方法,但是由于我正在研究Angular项目,因此我希望使用纯JS或打字稿来实现。
我的问题是我可能会得到一个包含重复条目的数组,例如:
data [0: {Id: 1, Definition: "House"},
1: {Id: 1, Definition: "House"}]
我想过滤掉它,让我只得到
data [0: {Id: 1, Definition: "House"}]
我已经尝试过使用此方法,但仍然会得到重复的条目
let uniqueArray = data.filter(function(item, pos) {
return data.indexOf(item) == pos;
})
答案 0 :(得分:4)
您可以通过这种方式实现您想要的:
您可以使用'some'
检查最终数组中是否已存在该值data = [{Id: 1, Definition: "House"}, {Id: 1, Definition: "House"}]
const finalOut = []
data.forEach((value) => {
if (!finalOut.some(x=> (x.Id === value.Id || x.Definition === value.Definition)))
{
finalOut.push(value)
}
})
您还可以通过'reduce'以简洁优雅的方式实现这一目标:
const finalOut2 = data.reduce((acc, cur) => acc.some(x=> (x.Id === cur.Id || x.Definition === cur.Definition)) ? acc : acc.concat(cur), [])
如@Ezequiel所建议,在some
或forEach
内使用reduce
,使时间复杂度为n平方的量。。对于较小的数据集,使用reduce
和some
是一种不错的方法。但是,如果要处理长度非常大的数组,则必须避免 n平方时间复杂度的顺序。这是filter
的一种这样的方法:
//Here storing every value of data is inside lookupObj after filtering it.
//And checking if value is filtered based on if key of the value inside lookupObj
const lookupObj = {}
const finalOut3 = data.filter(
x => {
const is_unique = !(lookupObj[`Id_${x.Id}`] || lookupObj[`Id_${x.Definition}`])
lookupObj[`Id_${x.Id}`] = true
lookupObj[`Id_${x.Definition}`] = true
return is_unique
}
)
答案 1 :(得分:1)
您可以使用对象的Id
键在对象累加器中使用array#reduce
获取唯一对象,并使用Object.values()
获取该对象的所有对象。
let data = [{Id: 1, Definition: "House"},{Id: 1, Definition: "House"}, {Id: 2, Definition: "House2"}, {Id: 2, Definition: "House2"}],
result = Object.values(data.reduce((r, o) => {
r[o.Id] = r[o.Id] || {...o};
return r;
},{}));
console.log(result);
答案 2 :(得分:0)
如果ID是确定身份的要素,则可以使用Map或普通对象进行重复数据删除。相同的ID将在地图上占据相同的位置,因此最终会得到唯一的对象(如果上述关于ID的假设成立)。
let data = [{Id: 1, Definition: "House"}, {Id: 1, Definition: "House"}];
let idToObj = {};
data.forEach((o) => idToObj[o.Id] = o);
let uniqueArray = Object.values(idToObj);
编辑:如果您想要相同但可能具有相同ID但其他字段不同的对象,则Map会派上用场,因为它可以将整个对象用作键:
let data = [{Id: 1, Definition: "House1"}, {Id: 1, Definition: "House2"}];
let map = new Map();
data.forEach((o) => map.set(o, true));
let uniqueArray = [...map.keys()];