问题
I seem to only find ways to remove duplicates from an array using other JS libraries but I'm looking to do it in pure JS or typescript since I'm working on an Angular project.
My problem is that I may get an array that has duplicate entries, such as this one:
data [0: {Id: 1, Definition: "House"},
1: {Id: 1, Definition: "House"}]
And I want to filter it out so that I only get
data [0: {Id: 1, Definition: "House"}]
I've tried it using this method but I still get duplicate entries
let uniqueArray = data.filter(function(item, pos) {
return data.indexOf(item) == pos;
})
回答1:
You can achieve what you want in this way:
You can check if the value is already there in your final array using '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)
}
})
You can also achieve this by 'reduce' in clean and elegant way:
const finalOut2 = data.reduce((acc, cur) => acc.some(x=> (x.Id === cur.Id || x.Definition === cur.Definition)) ? acc : acc.concat(cur), [])
As suggested by @Ezequiel using some
inside forEach
or reduce
making the time complexity of order of n square. For smaller sets of data using reduce
and some
is an elegant approach. But if you are dealing with arrays of very large length, you must avoid order of n square time complexity Here is one such approach with 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
}
)
回答2:
You can use Id
key of the object to get the unique object using array#reduce
in an object accumulator and get all the object of this object using 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);
回答3:
If the ID is what determines identity, then you could use a Map or a plain Object to dedupe. Same IDs will take the same spot on the map, so you end up with unique objects (if the above assumptions about IDs hold).
let data = [{Id: 1, Definition: "House"}, {Id: 1, Definition: "House"}];
let idToObj = {};
data.forEach((o) => idToObj[o.Id] = o);
let uniqueArray = Object.values(idToObj);
EDIT: In case that you want the same but you may have objects with the same ID but differing in other fields, a Map comes in handy because it can take whole objects as keys:
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()];
来源:https://stackoverflow.com/questions/52514026/remove-duplicate-in-array-using-pure-javascript-or-typescript