8

I'm struggling with something that should be very simple. I have an array of objects. I need to remove duplicate from this array based on the id property. So I want to create a Set containing my ids, like this:

let myArray = [{
    id: 10,
    other: "bla"
  },
  {
    id: 15,
    other: "meh"
  },
  {
    id: 10,
    other: "bla"
  }
]

let indexes = new Set();
myArray.forEach(a => indexes.add(a.id));
console.log('indexes list', indexes)

But indexes is always empty. What am I doing wrong? Thanks.

EDIT: I chose @Hyyan Abo Fakher's as correct answer because he was right, but the suggestion in @bambam comment was a great solution to the whole problem. Thanks to everyone.

6
  • 1
    Which browser and version are you using? Try console.log(Array.from(indexes)) Anyways. Just using reduce will be easier const unique = arr.reduce((a,b) => a.find(({id}) => id === b.id) ? a : a.concat(b) , []); Commented Jul 25, 2018 at 11:24
  • 3
    Can't reproduce. Are you sure your this.myArray isn't empty? Commented Jul 25, 2018 at 11:24
  • duplicate:stackoverflow.com/questions/9229645/… Nice solution: Use the ECMA6 Set Commented Jul 25, 2018 at 11:32
  • Your code works. why are using this.myArray Share complete snippit Commented Jul 25, 2018 at 11:35
  • 1
    @Archer: yeah, hate those MIA OPs :) Commented Jul 25, 2018 at 11:47

4 Answers 4

9

You could use filter method with Set to create new array of unique objects by id.

const data = [{id: 10, other: "bla"},{id: 15, other: "meh"},{id: 10, other: "bla"}]

let result = data.filter(function({id}) {
  return !this.has(id) && this.add(id);
}, new Set)

console.log(result)

Sign up to request clarification or add additional context in comments.

3 Comments

Really nice approach!
@Leonid Pyrlia Thank you.
I like this but did not work for me... Trying to understand why.
2

But indexes is always empty. What am I doing wrong?

Your code is completely functional, the issue seems to come from the browser console itself, you expect that printing the set to the console will print the items of the set as in arrays but in fact, the browser will print only the object instance

Running your code on StackOverflow will print indexes list {}, but in fact, the browser console printed something else.

enter image description here

To make sure the list is not empty use the size property

let myArray = [{
    id: 10,
    other: "bla"
  },
  {
    id: 15,
    other: "meh"
  },
  {
    id: 10,
    other: "bla"
  }
]

let indexes = new Set();
myArray.forEach(a => indexes.add(a.id));
console.log('indexes list', indexes.size)

To loop over the set you need to use for ... of

let myArray = [{
    id: 10,
    other: "bla"
  },
  {
    id: 15,
    other: "meh"
  },
  {
    id: 10,
    other: "bla"
  }
]

let indexes = new Set();
myArray.forEach(a => indexes.add(a.id));
for (let item of indexes) console.log(item);

Comments

1

You may check if the set has the ID, and if its not, then push the element to a new array. The final array will have the unique elements.

var source = [
  {id: 10, other: "bla"},
  {id: 15, other: "meh"},
  {id: 10, other: "bla"}
];

var set = new Set();
var result = [];

source.forEach(item => {
  if (!set.has(item.id)) {
    set.add(item.id);
    result.push(item);
  }
})

console.log(result);

2 Comments

Why push to a new array when you can just use the set?
@Barmar -- The set only contains the IDs of the objects.
1

Simply we can use arrays to resolve this issue with help of loop. like below:

var b = [];
a.forEach(function(index){
   if(b[index.id]==undefined){
       b[index.id] = index.other;
   }
});
console.log(b);

Here a is the original source array.

5 Comments

Why are you assigning to b[index.id] twice?
initially b[index.id] will be undefined, so it should be initiated before adding some values into it.
@BannarisamyShanmugam: but you're not adding any values to it.
You don't need to create a property or initialise anything. You can just get rid of b[index.id] = ""; as it is not required at all.
@Archer, You are right. I dont need to initiate it. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.