Reputation: 584
I have an array of hashes, like this:
[{id: "4bf58dd8d48988d110941735", name: "italy"},
{id: "4bf58dd8d48988d1c6941735", name: "skandi"},
{id: "4bf58dd8d48988d147941735", name: "diner"},
{id: "4bf58dd8d48988d110941735", name: "italy"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"},
{id: "4bf58dd8d48988d14a941735", name: "vietnam"},
{id: "4bf58dd8d48988d1ce941735", name: "fish"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"}]
I want to throw out duplicate hashes. Set doesn't work because hashes are unique objects.
I feel stuck and need a kick to think. Please advise!
Upvotes: 10
Views: 1392
Reputation: 92347
Try this
h.filter(( t={}, a=>!(t[a.id]=a.id in t) ))
Input array in h, time complexity O(n), explanation here.
let h = [{id: "4bf58dd8d48988d110941735", name: "italy"},
{id: "4bf58dd8d48988d1c6941735", name: "skandi"},
{id: "4bf58dd8d48988d147941735", name: "diner"},
{id: "4bf58dd8d48988d110941735", name: "italy"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"},
{id: "4bf58dd8d48988d14a941735", name: "vietnam"},
{id: "4bf58dd8d48988d1ce941735", name: "fish"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"}]
let t; // declare t to avoid use global (however works without it too)
let r= h.filter(( t={}, a=>!(t[a.id]=a.id in t) ))
console.log(JSON.stringify(r));
Upvotes: 6
Reputation: 13791
You can use reduce too
//I added comma to each object
const data= [{id: "4bf58dd8d48988d110941735", name: "italy"},
{id: "4bf58dd8d48988d1c6941735", name: "skandi"},
{id: "4bf58dd8d48988d147941735", name: "diner"},
{id: "4bf58dd8d48988d110941735", name: "italy"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"},
{id: "4bf58dd8d48988d14a941735", name: "vietnam"},
{id: "4bf58dd8d48988d1ce941735", name: "fish"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"},
{id: "4bf58dd8d48988d1c4941735", name: "resto"}]
const result= data.reduce((current,next)=>{
if(!current.some(a=> a.name === next.name)){
current.push(next);
}
return current;
},[])
console.log(result);
Upvotes: 7
Reputation: 537
Space for time
let arr = [
{ id: '4bf58dd8d48988d110941735', name: 'italy' },
{ id: '4bf58dd8d48988d1c6941735', name: 'skandi' },
{ id: '4bf58dd8d48988d147941735', name: 'diner' },
{ id: '4bf58dd8d48988d110941735', name: 'italy' },
{ id: '4bf58dd8d48988d1c4941735', name: 'resto' },
{ id: '4bf58dd8d48988d14a941735', name: 'vietnam' },
{ id: '4bf58dd8d48988d1ce941735', name: 'fish' },
{ id: '4bf58dd8d48988d1c4941735', name: 'resto' },
{ id: '4bf58dd8d48988d1c4941735', name: 'resto' }
]
let map = {};
let rest = arr.filter((item) => {
if(map[item.id] === void 0) {
map[item.id] = item.id;
return true;
}
});
map = null;
console.log(rest);
Upvotes: 4
Reputation: 6074
I would suggest an approach with associative arrays, this makes duplicate removal easier. If you can, you should build your array as an associative array in the first place, so that you don't have to convert it. Here is how you do it:
var array = [{
id: "4bf58dd8d48988d110941735",
name: "italy"
},
{
id: "4bf58dd8d48988d1c6941735",
name: "skandi"
}, {
id: "4bf58dd8d48988d147941735",
name: "diner"
}, {
id: "4bf58dd8d48988d110941735",
name: "italy"
}, {
id: "4bf58dd8d48988d1c4941735",
name: "resto"
}, {
id: "4bf58dd8d48988d14a941735",
name: "vietnam"
}, {
id: "4bf58dd8d48988d14a941735",
name: "fish"
}, {
id: "4bf58dd8d48988d1c4941735",
name: "resto"
}, {
id: "4bf58dd8d48988d1c4941735",
name: "resto"
}
];
// you can access the array with arrayAssociative[id], where the id is the real id like "4bf58dd8d48988d110941735"
var arrayAssociative = {};
for (item in array) {
// first get the unique id's
var addedNode = arrayAssociative[array[item].id] = arrayAssociative[array[item].id] || {};
if (addedNode.names == null)
addedNode.names = {};
// now get the unique names
var addedName = arrayAssociative[array[item].id].names[array[item].name] = arrayAssociative[array[item].id].names[array[item].name] || {};
}
console.log(arrayAssociative);
I don't know the exact reason, why the line
var element = arrayAssociative[id] =arrayAssociative[id] || {};
works for this, but let's just accept the funcitonality as it is :)
Upvotes: 2