name
name

Reputation: 235

Cant figure out why list filter is not acting correctly

Consider this code

const b = {
  users: [
    {
      "name": "bob",
      "id": 0
    },
    {
      "name": "sam",
      "id": 1
    },
    {
      "name": "tom",
      "id": 2
    },
  ]
}

const include = [1]
const c = b.users.filter(user => user.id in include)
console.log(c)

In my array include, I have the number 1 which references the id in the user object. c should return the "sam" one but instead returns "bob" who has id 0. I'm not understanding why ?

 > console.log(c)
 users: [
 {
     "name": "bob",
     "id:" 0
 }]

Upvotes: 2

Views: 56

Answers (4)

Kevin Amiranoff
Kevin Amiranoff

Reputation: 14468

Just adding to the other response,

The reason you get bob is that in returns true/false if it finds value at the index.

In your filter, user.id in include returns true if user.id is 0 and false otherwise because your include const has a length of 1, and include[0] returns 1.

Have a look at this example:

// Arrays
let trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']
0 in trees        // returns true
3 in trees        // returns true
6 in trees        // returns false

You can see the result produced in your filter, with a console.log:

const include = [1]
const c = b.users.filter(user => {
  console.log(user.id in include);
  return user.id in include
  })
console.log(c)

Upvotes: 0

Nonik
Nonik

Reputation: 655

const include = [1];
const c = b.users.filter(user =>   include.indexOf(user.id)>=0)
console.log(c)

Upvotes: 0

Unmitigated
Unmitigated

Reputation: 89204

Use Array#includes instead.

const c = b.users.filter(user => include.includes(user.id))

Better yet, use the more efficient Set.

const include = new Set([1])
const c = b.users.filter(user => include.has(user.id))

Upvotes: 1

CherryDT
CherryDT

Reputation: 29012

The in operator checks whether the given key exists in an object.

For example:

const obj = { a: 1, b: 2, c: 3 }

console.log('a' in obj) // true
console.log('x' in obj) // false

The array [1], when looked at as an object, looks something like { 0: 1, length: 1, ... }.

0 in [1] will be true (since [1][0] exists - it's the first and only element), but 1 in [1] will be false (since [1][1] doesn't exist, it would be the second element).

To check whether an array contains a certain value, you need Array.prototype.includes:

const c = b.users.filter(user => include.includes(user.id))

Upvotes: 4

Related Questions