0

I am new to JavaScript and I am learning a little about High Order Functions. I was wondering if someone can tell me why:

function filter_list(arr) {
  return arr.filter(function(item) {
    return typeof(item) == 'number';   
  });
}
// input = [1,'a','b',0,15] output = [1,0,15]

But

function filter_list(l) {
  return l.filter(function(item){
    if (typeof item == "number") {
      return item;
    }
  });
}
// input = [1,'a','b',0,15] output = [1,15]

I am having a hard time seeing the difference.

Raymond
  • 41
  • 1
  • 7

8 Answers8

1

Filter

Filter returns a value if a condition is true and ignores it if it is false

function filter(arr) {
  return arr.filter(function(x) {
    return x
  })
}

const booleans = [false, false, true]


// this logs only "true"
console.log(filter(booleans))

Truthy and Falsy

Additional to true and false there is truthy and falsy. This means that values evaluat to true or false in condition statements. You can read more on mdn

function getBooleanValue(value) {
  return !!value
}

console.log('1 gets cast to:', getBooleanValue(1))
console.log('0 gets cast to:', getBooleanValue(0))

Your Code

The second code snippet didn't returns the 0 because it gets cast to false. To get the expected array you have to change the return value from item to true

function filter_list(l) {
  return l.filter(function(item) {
    if (typeof item == "number") {
      return true;
    }
    return false
  });
}

console.log(filter_list([1, 'a', 'b', 0, 15]))
Roman
  • 4,922
  • 3
  • 22
  • 31
0

This is the 'beauty' of javascript. At your first example you return a boolean in your filter. the type of item is equal to number or it isn't

In the second example you return the item itself. So you return 1, 0 and 15. Because 1 is true and 0 is false in programming, javascript sees the returning 0 as a filter failure. So it is filtered. In other words, everything different from 0 is true, and 0 is false.

Jasper Seinhorst
  • 1,056
  • 6
  • 19
0

In the second case:

function filter_list(l) {
  return l.filter(function(item){
    if (typeof item == "number") {
      return item;
    }
  });
}

item 's value is used to filter or not itself. When item is worth 0, it's equivalent to false therefore, it's not included in the result. The function passed to filter expects a boolean result, if you do not return a boolean, you have to understand how javascript will interprete it.

Check it by yourself, 0 is equivalent false, therefore, if you return 0, the element is going to be filtered:

console.log(false == 0)
sjahan
  • 5,720
  • 3
  • 19
  • 42
0

Filter checks for Boolean values, it will take 0 and 1 as true and false, so if false == 0, the return 0 wont work.

console.log(filter_list([1,'a','b',0,15]));

function filter_list(l) {
  return l.filter(function(item){
    if (typeof item == "number") {
      return item;
    }
  });
}
Marco Salerno
  • 5,131
  • 2
  • 12
  • 32
0

This is because JavaScript has falsy values. Javascript takes null, undefined, 0 & false as falsy.

function filter_list(arr) {
  return arr.filter(function(item) {
    return typeof(item) == 'number';   
  });
}
// input = [1,'a','b',0,15] output = [1,0,15]

in this function you return boolean after comparing type, in which case each item that returns true in comparison is selected.

while in this function you are returning values instead of result of comparison, since 0 is falsy value it doesn't get selected for your filtered list.

function filter_list(l) {
  return l.filter(function(item){
    if (typeof item == "number") {
      return item;
    }
  });
}
// input = [1,'a','b',0,15] output = [1,15]
Muhammad Faizan
  • 1,709
  • 1
  • 15
  • 37
0

Filter expects you to provide a boolean variable. This is done in your first example. The second example is just possible because Javascript is not using static types. The item 0 interpreted as boolean is false. So if you do return 0, filter does not append the item.

ByteHamster
  • 4,884
  • 9
  • 38
  • 53
0

The two examples you have provided are not at all equivalent.

In the first example you are returning the result of evaluating the expression typeof(item) == 'number' which will either be true or false depending.

In the second you have three fairly different possibilities.

The first two are covered by the if statement: if the type of the item is number you are returning the item itself which may be 'falsey' (zero or NaN) and thus fail the filter or 'truthy' (anything but zero or NaN).

But there's also an implicit return of undefined if the type of item is not number. This doesn't have an impact in a filter because undefined is falsey, but you will likely get unexpected results using copying this pattern to use elsewhere and it should be avoided.

Jared Smith
  • 19,721
  • 5
  • 45
  • 83
0

It's because the Array.prototype.filter() creates a new array with all elements for which the test function returns a truthy value (see here: Understanding JavaScript Truthy and Falsy)

And because 0 is falsy it's not part of the returned array in the second sample.

fboers
  • 126
  • 8