2012-02-02 13 views
29

¿Cuál es la forma más bonita de comparar un valor con las opciones de múltiplos?Javascript: la manera más bonita de comparar un valor con varios valores

Sé que hay muchas maneras de hacerlo, pero estoy buscando lo mejor.

lo pregunto porque yo esperaba que esto era viable (que no es, evidentemente, cuando se mire):

if (foobar == (foo||bar)) { 
    //do something 
} 
+0

Puede usar la función de prueba de javascript como 'if (/foo|bar|ow|my|javascript|works/.test (foobar)) {/ * hacer algo * /}' Esta pregunta [similar a la mía] (http://stackoverflow.com/questions/12743248/how-to-nest-or-statements-in-javascript) –

Respuesta

51

No intente ser demasiado furtivo, especialmente cuando afecte innecesariamente el rendimiento. Si realmente tiene un montón de comparaciones que hacer, simplemente formatee bien.

if (foobar === foo || 
    foobar === bar || 
    foobar === baz || 
    foobar === pew) { 
    //do something 
} 
+0

Finalmente te di esto porque es la respuesta más legible, incluso si no es la más innovadora. – thelastshadow

+8

Puede acelerarlo si ordena los términos con probabilidad descendente para que sean ciertos. :) – wenzul

+2

¡El mejor consejo que recibiré hoy! :) – Codeformer

13

Se puede utilizar un interruptor:

switch (foobar) { 
    case foo: 
    case bar: 
    // do something 
} 
+0

hmm. Este me intriga, pero me preocupa su legibilidad. – thelastshadow

+0

puede usar esto para listas dinámicas de valores a través de – caleb

+3

¿Por qué el voto a favor? Si no explica qué es lo que cree que está mal, no puede mejorar la respuesta. – Guffa

47

Lo i uso para hacer, es poner los múltiples valores en una matriz como

var options = [foo, bar]; 

y luego, usar indexOf()

if(options.indexOf(foobar) > -1){ 
    //do something 
} 

de hermosura:

if([foo, bar].indexOf(foobar) +1){ 
    //you can't get any more pretty than this :) 
} 

y para los navegadores antiguos:
(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/IndexOf)

if (!Array.prototype.indexOf) { 
    Array.prototype.indexOf = function (searchElement /*, fromIndex */) { 
     "use strict"; 
     if (this == null) { 
      throw new TypeError(); 
     } 
     var t = Object(this); 
     var len = t.length >>> 0; 
     if (len === 0) { 
      return -1; 
     } 
     var n = 0; 
     if (arguments.length > 0) { 
      n = Number(arguments[1]); 
      if (n != n) { // shortcut for verifying if it's NaN 
       n = 0; 
      } else if (n != 0 && n != Infinity && n != -Infinity) { 
       n = (n > 0 || -1) * Math.floor(Math.abs(n)); 
      } 
     } 
     if (n >= len) { 
      return -1; 
     } 
     var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); 
     for (; k < len; k++) { 
      if (k in t && t[k] === searchElement) { 
       return k; 
      } 
     } 
     return -1; 
    } 
} 
+1

'indexOf' para matrices solo se proporciona en IE comenzando con la versión 9, por lo que evitaría usarlo hasta que 8 salga del mercado (a grandes distancias, por desgracia). Dicho esto, el [MDN] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf) proporciona un ejemplo de código de implementación para los navegadores que no lo admiten. – Reid

+1

El método 'Array.indexOf' solo es compatible con Javascript 1.6 y versiones posteriores, por lo que necesita un respaldo para navegadores más antiguos. – Guffa

+0

Reid: Buen punto. André: Tu edición está perdiendo foobar, pero ciertamente está limpio. – thelastshadow

11

Ya que nadie ha añadido la solución obvia pero que funciona bien para dos comparaciones, yo Lo ofreceré:

if (foobar == foo || foobar == bar) { 
    //do something 
} 

Y, si usted tiene un montón de valores, entonces yo sugeriría hacer un Conjunto ya que esto hace que el código comparación muy limpia y sencilla y es rápido en tiempo de ejecución:

// pre-construct the Set 
var tSet = new Set([foo, bar, test1, test2, test3]); 

// test the Set at runtime 
if (tSet.has(foobar)) { 
    // do something 
} 

Para pre-ES6, se puede obtener una Establecer polyfill de los cuales hay muchos. Uno se describe en este other answer.

+0

:) tal vez demasiado obvio. Está bien hasta que tenga cuatro valores para comparar con una variable. – thelastshadow

0

(foobar == foo || foobar == bar) de lo contrario, si está comparando expresiones basadas solo en un entero único, valor enumerado u objeto String, puede usar el interruptor. Ver The switch Statement. También puede usar el método sugerido por André Alçada Padez. En última instancia, lo que seleccione tendrá que depender de los detalles de lo que está haciendo.

15

Sólo por diversión, ya que este Q & A parece estar a punto de microanálisis de sintaxis, una pequeña pequeña modificación de la sugerencia (s) de André Alçada Padez:

(y, por supuesto, lo que representa el pre -IE9 cuña/navaja/polyfill que está incluido)

if (~[foo, bar].indexOf(foobar)) { 
    // pretty 
} 
6

Por qué no usar indexOf de la matriz como abajo?

if ([foo, bar].indexOf(foobar) !== -1) { 
    // do something 
} 

Sólo una simple Javascript, no hay marcos o bibliotecas pero será not work on IE < 9.

0

El método de cambio (como lo menciona Guffa) funciona muy bien. Sin embargo, la configuración de advertencia predeterminada en la mayoría de los linters lo alertará sobre el uso de Fall-Through. Es una de las principales razones por las que utilizo interruptores, por lo que prácticamente ignoro esta advertencia, pero debe tener en cuenta que el uso de la función de derivación de la declaración de cambio puede ser complicado. En casos como este, sin embargo, yo iría por eso.

+0

@Rahul solo editando en los backticks es ** NO ** * Se realiza el formateo correcto * – rene

1

Me gusta la forma bonita de probar indexOf con una matriz, pero tenga en cuenta que esto no funciona en todos los navegadores (because Array.prototype.indexOf is not present in old IExplorers).

Sin embargo, hay una forma similar mediante el uso de jQuery con la función $.inArray():

if ($.inArray(field, ['value1', 'value2', 'value3']) > -1) { 
    alert('value ' + field + ' is into the list'); 
} 

Podría ser mejor, lo que no debería probar si existe indexOf.

Tenga cuidado con la comparación (no use == verdadero/falso), porque $ .inArray devuelve el índice de posición coincidente donde se ha encontrado el valor, y si el índice es 0, sería falso cuando realmente existe en la matriz.

Cuestiones relacionadas