Dende
Dende

Reputation: 584

Filtering duplicate hashes from array of hashes - Javascript

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

Answers (4)

Kamil Kiełczewski
Kamil Kiełczewski

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

Just code
Just code

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

zheng li
zheng li

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

Stephan T.
Stephan T.

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

Related Questions