Max Doung
Max Doung

Reputation: 221

How does the indexOf method is returning the falsely value?

function bouncer(arr) {
  var array = [false, null, 0, NaN, undefined, ""];
  var result = [];
  for (var i = 0; i < arr.length; i++) {
      if (array.indexOf(arr[i]) === -1) {
          result.push(arr[i]);
      }
  }
  return result;
}
ex : bouncer([7, "ate", "", false, 9]) should return [7, "ate", 9].

Hello Everyone, I am trying to delete all the falsely values that are in the array input, but for somehow when I run bouncer([false,null, 0, NaN, undefined, ""]); I get [NaN] as a return value while I am expecting an empty array. Does anyone know why the function is returning the falsely values ?

Upvotes: 1

Views: 79

Answers (3)

paxdiablo
paxdiablo

Reputation: 882596

It's because NaN is really a concept rather than a concrete number.

Consider the two "numbers" 0 / 0 and sqrt(-1). Neither of these are defined in the real number space so both give NaN, but they are clearly different values.

Because NaN basically indicates an unknown value that couldn't be represented in IEEE-754, it is never considered equal to another NaN, even itself.

This is the right thing to do because, given the infinitude (literally) of numbers that have no real representation in IEEE-754, the chances of two of them being the same number are infinitesimally small :-)

In fact, many implementations of isNaN() depend on this feature, to wit (pseudo-code):

define isNaN(n):
    return n != n

To actually solve this problem, one way is to remove the NaN from the checking array and slightly modify the conditional:

var array = [false, null, 0, undefined, ""];
:
if ((array.indexOf(arr[i]) === -1) && (! isNaN(arr[i])) {

Upvotes: 5

Dekel
Dekel

Reputation: 62676

As already mentioned - NaN is (by design) not equal to anything (not even itself).

To solve your problem you can add the arr[i] === arr[i] to your if(...):

function bouncer(arr) {
  var array = [false, null, 0, undefined, ""];
  var result = [];
  for (var i = 0; i < arr.length; i++) {
      if (array.indexOf(arr[i]) === -1 && (arr[i] === arr[i])) {
          result.push(arr[i]);
      }
  }
  return result;
}
console.log(bouncer([7, "ate", "", false, 9]));
console.log(bouncer([false,null, 0, NaN, undefined, ""]));

Upvotes: 0

Nick Broderick
Nick Broderick

Reputation: 289

There is already an answer that explains why NaN is included in your result. As to a solution to your problem, the following should suffice:

function bouncer(arr) {
  return Array.isArray(arr) ? arr.filter(v => v) : undefined;
}

The idea here is we filter out the values which coerce to true in a boolean context. Thus, the function we use to filter just returns the value itself!

Upvotes: 0

Related Questions