'Remove array duplicates by property javascript
I have a list of objects:
[{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]
I need a simple way to filter out duplicates with regard to the name property, so:
[{name: "bob", age: "14"}, {name: "sue", age: "21"}]
There seem to be quite a few array duplicate removal questions, but not any based on a property. It can ignore all other fields.
Solution 1:[1]
Iterate the array, place all name
values in a hash and skip objects whose name
is already in the hash:
filterBy = function(ary, prop) {
var seen = {};
return ary.filter(function(item) {
var key = item[prop];
if(seen[key] === 1)
return false;
seen[key] = 1;
return true;
});
}
//
a = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]
b = filterBy(a, 'name');
console.log(b);
ES6 version:
filterBy = function(ary, prop) {
var seen = new Set();
return ary.filter(item => !seen.has(item[prop]) && seen.add(item[prop]));
}
a = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]
b = filterBy(a, 'name');
console.log(b);
Solution 2:[2]
You can do it with 2 for loops as follows. All you have to do is, keeping a result array and every time you insert into it, check whether the name attributes are equal.
function findDuplicate(){
var array= [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}];
var result=[];
for(x in array){
var found=false;
for(y in result){
if(result[y].name.localeCompare(array[x].name)==0){
found=true;
}
}
if(!found){
result.push(array[x]);
}
}
console.log(result);
}
Solution 3:[3]
You could do this with forEach
and thisArg
param.
var data = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}];
var result = [];
data.forEach(function(e) {
if (!this[e.name]) {
this[e.name] = e;
result.push(this[e.name]);
}
}, {});
console.log(result)
Or with forEach
and map()
var data = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}], result =[];
data.forEach(function(e) {
if(result.map(a => {return a.name}).indexOf(e.name) == -1 ) result.push(e);
});
console.log(result)
Solution 4:[4]
You could use Array#filter
and a this
object for marking, if the same name is already filtered.
var array = [{ name: "bob", age: "14" }, { name: "bob", age: "16" }, { name: "sue", age: "21" }],
filtered = array.filter(function (a) {
if (!this[a.name]) {
this[a.name] = true;
return true;
}
}, Object.create(null));
console.log(filtered);
Solution 5:[5]
For the straightforward comparison in the Q., there are some good answers here. If you want to provide a custom comparison function that will work on e.g. object values, or that uses a RegExp, then take a look at the following.
var dedupwhen = function(fn, list){
if(list[0] === undefined){
return [];
}
// Join the first item to the remainder that has had the first
// item filtered out (according to fn) and then been
// deduplicated itself.
return [list[0]].concat(dedupwhen(fn, list.slice(1).filter(function(item){
return !fn(list[0], item);
})));
};
var similarname = function(x,y){
return RegExp('^' + x.name + '$', 'i').test(y.name);
};
var list = [
{name: 'Sue', age: 44},
{name: 'Bob', age: "14"},
{name: 'bob', age: "16"},
{name: 'sue', age: "21"}
];
console.log(dedupwhen(similarname, list));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | georg |
Solution 2 | |
Solution 3 | |
Solution 4 | |
Solution 5 |