Barkork
Barkork

Reputation: 55

Filterring an Array of Objects

Im trying to do a check if one of the objects in the Array has the id of 2 if so remove that object. list.filter(e => e.id === 2) returns[ { name: 'bread', id: 2 } ] which is the part i want to remove but if i check if it is in the array by doing if(list.indexOf(list.filter(e => e.id === 2)) != -1) it returns -1 saying its not in the list. Any help would be apreciated!

var list = new Array();
list.push({name: 'apple', id: 1})
list.push({name: 'bread', id: 2})
console.log(list.filter(e => e.id === 2));
console.log(list);
if(list.indexOf(list.filter(e => e.id === 2)) != -1) {
    list.splice(list.indexOf(list.filter(e => e.name === 2)));
    console.log(list);
} else {
    console.log('The id of 2 has not been found');
}

Upvotes: 2

Views: 87

Answers (6)

BotNet
BotNet

Reputation: 2809

indexOf won't work as you will be searching for an object and object comparison in JavaScript is tricky (a custom evaluater is needed to check sameness). The good news is you may not need it.

As noted in comments and elsewhere, filter was behaving opposite to what you desired. Changing the comparison operator from === to !== is one way to solve that issue.

In the code below, I've included some other goodies you may find value, such as:

  • the Array.of()
  • shorthand property names (e.g., { foo } === {'foo': foo})
  • series execution using the comma operator (i.e. ,) especially to avoid curly-braces
  • ... as a rest operator for function arguments
  • and others

let search_id = 2;             // id to filter out

let list = Array.of(
 {name: 'apple',  id: 1},
 {name: 'bread',  id: 2},
 {name: 'orange', id: 3},
 {name: 'bagel',  id: 4}
)
log({list});


let filtered = list.filter(e => e.id !== search_id)
log({filtered});


if (filtered.length)
  log(`Found ${filtered.length} matches!`);
else
  log(`The id of ${search_id} has not been found`);




// Simple logger so label is on its own line
function log(){
  let [param1,...args]=arguments;
  
  switch (typeof param1){
    case 'string': 
      if (args.length)
        console.log(`${param1}:`),  // comma intentional
        console.log(args.pop())
      else
        console.log(param1);
      break;
    case 'object':
      for (let key in param1)
        console.log(`${key}:`),   // comma intentional
        console.log(param1[key])
      break;
    default:
      console.log('Error in passed arguments.  Type not recognized.')
  }      
}

Upvotes: 0

Ethan Vu
Ethan Vu

Reputation: 2987

When you use list.filter(e => e.name === 2). It will return an array include the object , not the object itself. So it will return -1. You can use the spread syntax to extract the object out of the array contain it:

list.indexOf(...list.filter(e => e.id === 2))

Upvotes: 0

hsz
hsz

Reputation: 152206

Testing with indexOf you're searching for an array with the element that you've found.

filter returns an array with the results. You should use find instead which returns a single element:

var list = new Array();
list.push({name: 'apple', id: 1})
list.push({name: 'bread', id: 2})

var index = list.indexOf(list.find(e => e.id === 2));
var result = index !== -1;

console.log('index', index);
console.log('result', result);

Upvotes: 0

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48357

Then just use !== instead ===.

But you can use find method.

var elem = list.find(e => e.id === 2);
if(elem)
   list = list.filter(e => e.id !== 2);
else
   console.log('The id of 2 has not been found');

Upvotes: 1

Tsvetan Ganev
Tsvetan Ganev

Reputation: 8826

You need to invert the logic of the filter predicate function.

list.filter(e => e.id !== 2);

filter returns only the items that match the predicate - in your case it will return a list of only one element which has the ID of 2.

Upvotes: 0

Luca Kiebel
Luca Kiebel

Reputation: 10096

You are using filter, like it filters out elements, while it actually keeps elements that fit the condition. Change your condition to e.id !== 2 and it keeps all elements with ids not equal to 2:

var list = new Array();
list.push({name: 'apple', id: 1})
list.push({name: 'bread', id: 2})
list.push({name: 'milk', id: 3})
list.push({name: 'butter', id: 4})

console.log(list.filter(e => e.id !== 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Related Questions