2012-07-25 9 views
8

Dado que NaN === NaN evalúa a false, ¿es posible agregar un caso NaN a una declaración switch?¿Cómo se tiene un caso NaN en una declaración de interruptor?

Por ejemplo, digamos que quiero hacer el siguiente modificador:

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

Envío NaN como x irá al caso por defecto. Sé que hay formas de evitar el uso de NaN en declaraciones de cambio (por ejemplo, puedo rodear con una declaración if..else y usar isNaN), pero ¿hay un enfoque más directo?

+2

Creo que la única manera de hacerlo t el suyo es 'switch (true)' con sentencias 'case x === 1' y' case isNaN (x) '. No es la estructura más ideal, pero sí funciona. – Brad

+2

Puede hacer isNan en el caso predeterminado y cambiar su lógica según corresponda – nolegs

+1

Coloque 'case' blocks para cada otro posible valor de' x', y luego 'default' será' NaN'. :) – tenfour

Respuesta

6

Originalmente escribí que vi una sola solución, sin embargo, durante mi sueño, se me ocurrió una solución excelente.

Tenga siempre en cuenta que un interruptor no realiza una conversión de tipo implícita para comparar los casos, de modo que si proporciona una cadena a la instrucción switch no coincidirá con enteros en los casos, y viceversa. Si desea comparar cadenas y enteros, primero deberá convertir su número entero en una cadena y luego comparar solo con cadenas.

La solución excelente:

Como ha señalado WouterH, mi solución inicial se resolverá por defecto cuando se utiliza una cadena que contiene un número, este es el comportamiento esperado para declaraciones. Pero podría ser útil analizar el argumento para superar esto. Para que pueda utilizar siguiente código:

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; 
} 

Mi inicial método excelente:

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 devolverá verdadero si x donde sea una cadena, pero en realidad no importa porque la verdadera won No se evalúa como verdadero para una cadena debido al comportamiento mencionado anteriormente de la declaración de cambio.

Mi solución original:

Ni siquiera sé lo que estaba pensando, esto se ve horrible y la sangría es simplemente incómodo, pero gracias por los 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; 
} 

solución de Brad:

THX a Brad para éste. Realmente no me gusta esto porque se siente un poco como un truco, es decir, no es así como se esperaría el uso de una declaración de caso, pero le da la mayor flexibilidad, así que estoy seguro hay un caso de uso para eso.

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; 
} 
+1

lo siento, pero la excelente solución falla cuando pasa un número como una cadena: 'var x =" 1 ";' vea esto [jsFiddle] (http://jsfiddle.net/MAAV5/) –

+1

@WouterH, esto es el comportamiento esperado de una declaración de cambio, no realiza conversiones implícitas, como señalé explícitamente en mi publicación, consulte este jsFiddle para ver la prueba http://jsfiddle.net/DYcfP/1/ –

+0

Para 'x =" 1 "' Esperaría que alerta '1' o' IsNaN! ', Pero no' predeterminado'. –

2

@ La respuesta de helmus es correcta y es una buena solución.

Sin embargo, puede mantener el caso NaN si utiliza cadenas:

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

Eso funcionará siempre que sepa 'x' no es' nulo' o ' undefined'. Usted podría hacer 'x +" "' en su lugar. –

+0

Gracias, he corregido la respuesta :) –

+0

... y técnicamente hablando, 'NaN! ==" NaN "'. – josh3736

2

Por qué no simplemente hacer esto (jsFiddle):

var x = "test"; 
switch (isNaN(x) || 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; 
} 

O si también desea validar cadena que contiene una número (jsFiddle):

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; 
} 
+0

excelente sugerencia, lo optimicé y lo incluí en mi publicación. –

Cuestiones relacionadas