We have an array of elements that contains both truth and false values. Our job is to write a function that returns an array with indices of those elements which are NaN in the original array.
NaN !== NaN
The datatype of NaN is actually number. Although NaN is a falsy value, it has a peculiar property that no other datatype or variable has. It’s that the expression NaN === NaN yields false. And it’s only in the case of NaN that its false.
So, we can use this behavior to our good and pick out NaN value index. The code for this will be −
const arr = [7, 1, "123abc", undefined, NaN, 78, NaN, null, "aes", NaN, '', null, NaN]; const pickNaN = (arr) => { return arr.reduce((acc, val, ind) => { if(val !== val){ acc.push(ind); }; return acc; }, []); }; console.log(pickNaN(arr));
Using isNaN() / Number.isNaN()
The isNaN() function returns true or false based on the fact whether or not the value provided is a NaN or can be coerced to a NaN. Whereas the Number.isNaN() function only returns true if the value provided is actually NaN.
So, the Number.isNaN() is a reliable way of checking for NaN over isNaN(). The difference in the code outputs is illustrated below.
Example
const arr = [7, 1, "abc", undefined, NaN, 78, NaN, null, "aes", NaN, '', null, NaN]; const pickNaN = (arr) => { return arr.reduce((acc, val, ind) => { if(Number.isNaN(val)){ acc.reliableWay.push(ind); }; if(isNaN(val)){ acc.unreliableWay.push(ind); } return acc; }, { reliableWay: [], unreliableWay: [] }); }; console.log(pickNaN(arr));
This code prepares two arrays, one using Number.isNaN() and one using isNaN().
Output
The output will be −
{ reliableWay: [ 4, 6, 9, 12 ], unreliableWay: [ 2, 3, 4, 6, 8, 9, 12] }
We can clearly see how isNaN() computed many non-NaN values as NaN. That’s why Number.isNaN() is a more reliable way.