10

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!

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
Dende
  • 545
  • 6
  • 19

4 Answers4

7

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);
Just code
  • 13,553
  • 10
  • 51
  • 93
6

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));
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
4

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);
zheng li
  • 501
  • 1
  • 4
  • 10
2

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 :)

Stephan T.
  • 5,843
  • 3
  • 20
  • 42
  • 1
    `arrayAssociative[array[item].id] || {}` this line gives value in left of `||` if it is not null/undefined/0/false or value in the right if opposit - https://stackoverflow.com/q/2100758/860099 – Kamil Kiełczewski Dec 21 '18 at 10:03