1

I am trying to remove an object from an array if the age property matches using the below codes.

 var state= [
    {name: "Nityanand", age:23},
    {name: "Mohit", age:25},
    {name: "Nityanand", age:25}
  ]
  
  
 let a= [...state];
 var ids=[]

 var ar = a.filter(function(o) {
    
        if (ids.indexOf(o.age) !== -1){
        return false;
        }
        
        else if(ids.indexOf(o.age) === -1){
        ids.push(o);
        return true;}
})
console.log(ids)

    // OUTPUT: (NOT working fine)
    {name: "Nityanand", age:23},
    {name: "Mohit", age:25},
    {name: "Nityanand", age:25}

But if I edit the code by pushing only one property in the array, it is working fine:

 var state= [
    {name: "Nityanand", age:23},
    {name: "Mohit", age:25},
    {name: "Nityanand", age:25}
  ]
  
  
 let a= [...state];
 var ids=[]

 var ar = a.filter(function(o) {
    
        if (ids.indexOf(o.age) !== -1){
        return false;
        }
        
        else if(ids.indexOf(o.age) === -1){
        ids.push(o.age); // Here i have edited the code by pushing only age property to the array
        return true;}
})
console.log(ids)

OUTPUT : [23, 25] // Only two items were added.

There is no difference in the Conditions but in the first code's output 3 items were added in the empty array while in the second code only 2 items get added. How is this possible?

  • How is it possible? When `ids` is `[{name: "Nityanand", age:23},{name: "Mohit", age:25}]` and you ask for the index of `25`, what should it return? Because `{name: "Mohit", age:25} === 25` returns false... – Heretic Monkey Mar 29 '21 at 16:21
  • Does this answer your question? [How to remove all duplicates from an array of objects?](https://stackoverflow.com/questions/2218999/how-to-remove-all-duplicates-from-an-array-of-objects) – Heretic Monkey Mar 29 '21 at 16:23
  • As {name: "Mohit", age:25} === 25 returns false, then Why it is pushing {name: "Mohit", age:25} in the empty array. See my first code Output. – Kr Nityanand Mar 29 '21 at 16:29
  • Some general points: 1) doesn't look like you need to copy `state` to `a` as filter already returns a new array, 2) filter does not return a boolean on all paths so your code lacks clarity in behaviour, 3) indexOf is not as efficient as a Set for example, 4) A Set would already ensure there weren't dupes too 5) you call indexOf unnecessarily twice – Dominic Mar 29 '21 at 16:31

1 Answers1

0

In your first example, you're pusing the entire object to array ids but attempting to match if the age is present using indexOf - that will not work. You'll never find the object with property age which matches. You can achieve much the same using findIndex

var state = [{
    name: "Nityanand",
    age: 23
  },
  {
    name: "Mohit",
    age: 25
  },
  {
    name: "Nityanand",
    age: 25
  }
]


let a = [...state];
var ids = []

var ar = a.filter(function(o) {
  const idx = ids.findIndex(id => id.age == o.age);
  if (idx !== -1) {
    return false;
  } else if (idx === -1) {
    ids.push(o);
    return true;
  }
})
console.log(ids)
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • Thanks for your solution. But I need to understand when I am trying to match if the age is present using indexOf - that is not working. While I am using the same condition in the second code and I am able to match the age property using indexOf. The only difference in the second code is that I am pushing only age property in the empty array rather than pushing the whole item. – Kr Nityanand Mar 29 '21 at 16:34
  • @KrNityanand Because in the second example your putting the actual age into the array (`ids.push(o.age);`) not the object (`ids.push(o)`). – Jamiec Mar 29 '21 at 16:36
  • Thanks a lot I Got it! – Kr Nityanand Mar 29 '21 at 16:38
  • @KrNityanand see my update - uses `findIndex` instead of `find` so you can see you can still get the required index – Jamiec Mar 29 '21 at 16:39