Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you have a NaN case in a switch statement?

Tags:

javascript

Since NaN === NaN evaluates to false, is it possible to add a NaN case to a switch statement?

For example, let's say I want to make the following switch:

switch(x){
    case 1:
    case 2:
    case 4:
        doSomething();
        break;
    case NaN:
        doSomethingElse();
        break;
    case default:
        doADifferentThing();
        break;
}

Sending NaN as x will go to the default case. I know there are ways around using NaN in switch statements (e.g. I can surround with an if..else statement and use isNaN), but is there a more direct approach?

like image 872
Michael Holman Avatar asked Jul 25 '12 20:07

Michael Holman


People also ask

Can you have multiple cases in a switch statement?

As per the above syntax, switch statement contains an expression or literal value. An expression will return a value when evaluated. The switch can includes multiple cases where each case represents a particular value.

Does switch case use == or ===?

In answer to your question, it's === .

How many cases can switch statement have?

Microsoft C doesn't limit the number of case values in a switch statement. The number is limited only by the available memory. ANSI C requires at least 257 case labels be allowed in a switch statement.

Can Switch case have return statement?

The JavaScript switch statement can contain return statements if it is present inside a function.


1 Answers

I originally wrote i saw only one solution, however during my sleep i came up with a superb solution.

Always keep in mind that a switch does not do implicit type conversion to compare the cases so if you provide a string to the switch statement it will not match to integers in the cases, and vice versa. If you want to compare to strings and integers you will have to cast your integer to a string first and then compare to strings only.

The superb solution:

As pointed out by WouterH, my initial solution will resolve to default when using a string that contains a number, this is expected behavior for switch statements. But it might be useful to parse the argument in order to overcome this. For that you can use following code:

var x = "1";
switch (isNaN(x) || parseInt(x))
{
    case true:
      alert("IsNaN!") 
      break; 
    case 1: 
      alert("1"); 
      break; 
    case 2: 
      alert("2"); 
      break; 
    case 4: 
      alert("4"); 
      break; 
    default: 
      alert("default"); 
      break; 
}

My initial superb method :

var x = "clearly not a number";
switch(x){
    case !isNaN(x) || x:
      alert("IsNaN!")
      break;
    case 1:
      alert("1");
      break;
    case 2:
      alert("2");
      break;
    case 4:
      alert("4");
      break;
    default:
      alert("default");
      break;
    }

isNaN will return true if x where to be a string but it doesn't really matter because true won't evaluate as true to a string because of the above mentioned behavior of the switch statement.

My original solution:

I don't even know what i was thinking, this looks horrible and the indentation is just plain awkward, but thanks for the upvotes !

var x = "clearly not a number";
switch(x){
    case 1:
      alert("1");
      break;
    case 2:
      alert("2");
      break;
    case 4:
      alert("4");
      break;
    case default:
       if (isNaN(x)){
          alert("isNaN");
          break;
       }
       alert("default");
       break;
}

Brad's solution:

thx to Brad for this one. I don't really like this because it feels a bit like a hack, that is to say, this isn't how you would expect usage of a case statement, but it does give you the most flexibility, so i'm certain there is a use case for it.

var x = "clearly not a number";
switch(true)
{
   case x==1:
      alert("1");
      break;
   case x==2:
      alert("2");
      break;
   case IsNaN(x):
      alert("IsNaN");
      break;
   case default:
      alert("default");
      break;
}
like image 190
Willem D'Haeseleer Avatar answered Oct 13 '22 21:10

Willem D'Haeseleer