Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Array.filter(Number) filter zero out in JavaScript?

I'm trying to filter all non-numeric elements out from an array. We can see the desired output when using typeof. But with Number, it filters zero out.

Here's the example (tested in Chrome Console):

[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number) // Which output with zero filtered out: [-1, 1, 2, 3, 4]  // 0 is filtered 

If we use typeof, it doesn't filter zero, which was expected.

// code [-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(n => typeof n === 'number') // output [-1, 0, 1, 2, 3, 4, 0] 

My question:

  1. What is the difference between the 'Number' and 'typeof' approaches?

  2. Number filters zero, but 'Number' itself literally contains zero, and this confuses me.

like image 228
imckl Avatar asked Dec 25 '18 06:12

imckl


People also ask

How do array filters work in JavaScript?

JavaScript Array filter()The filter() method creates a new array filled with elements that pass a test provided by a function. The filter() method does not execute the function for empty elements. The filter() method does not change the original array.

Why filter function is not working in JavaScript?

To answer the question of filter and map, filter returns only those elements if the return value in the function is true. Map returns same number of elements, for the return of false value, the element returned would be undefined. One more thing, the map return a new array. Filter does not return a new array.

How do you filter an array of numbers?

Use the filter() method to filter an array to only numbers, e.g. arr. filter(value => typeof value === 'number') . The filter method returns an array with all the elements that satisfy the condition. In our case, all array elements with a type of number .

What is the output of the filter function in JavaScript?

The JavaScript filter array function is used to filter an array based on specified criteria. After filtering it returns an array with the values that pass the filter. The JavaScript filter function iterates over the existing values in an array and returns the values that pass.


2 Answers

Because 0 is one of the many falsy values in javascript

All these conditions will be sent to else blocks:

if (false) if (null) if (undefined) if (0) if (NaN) if ('') if ("") if (``) 

From the Array.prototype.filter() documentation:

filter() calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a value that coerces to true

In your case the callback function is the Number. So your code is equivalent to:

[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(a => Number(a))   // Number(0) -> 0 // Number(Number(0)) -> 0 // Number('') -> 0 // Number('test') -> NaN 

When filter function picks truthy values (or values that coerces to true), the items which return 0 and NaN are ignored. So, it returns [-1, 1, 2, 3, 4]

like image 102
adiga Avatar answered Sep 24 '22 02:09

adiga


To prevent a falsy zero from filtering, you could use another callback for getting only numerical values: Number.isFinite

console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
like image 20
Nina Scholz Avatar answered Sep 22 '22 02:09

Nina Scholz