else condicionales javascript if-statement

javascript - else - Cómo acortar mis declaraciones condicionales



condicionales en javascript (15)

Creo que hay 2 objetivos al escribir este tipo de condición.

  1. brevedad
  2. legibilidad

Como tal, a veces # 1 podría ser el más rápido, pero tomaré el # 2 para un fácil mantenimiento más adelante. Dependiendo del escenario, a menudo optaré por una variación de la respuesta de Walter.

Para comenzar, tengo una función disponible a nivel mundial como parte de mi biblioteca existente.

function isDefined(obj){ return (typeof(obj) != ''undefined''); }

y luego, cuando realmente quiero ejecutar una condición if similar a la suya, crearía un objeto con una lista de los valores válidos:

var validOptions = { "itema":1, "itemb":1, "itemc":1, "itemd":1 }; if(isDefined(validOptions[test.type])){ //do something... }

No es tan rápido como una declaración de interruptor / caja y es un poco más detallado que algunos de los otros ejemplos, pero a menudo obtengo una reutilización del objeto en otro lugar del código que puede ser bastante útil.

Llevando a cuestas en una de las muestras jsperf hechas anteriormente, agregué esta prueba y una variación para comparar velocidades. http://jsperf.com/if-statements-test-techsin/6 Lo más interesante que noté es que ciertos combos de prueba en Firefox son mucho más rápidos que incluso Chrome.

Esta pregunta ya tiene una respuesta aquí:

Tengo una declaración condicional muy larga como la siguiente:

if(test.type == ''itema'' || test.type == ''itemb'' || test.type == ''itemc'' || test.type == ''itemd''){ // do something. }

Me preguntaba si podría refactorizar esta expresión / declaración en una forma más concisa.

¿Alguna idea sobre cómo lograr esto?


De otra forma u otra manera increíble que encontré es esta ...

if (''a'' in oc([''a'',''b'',''c''])) { //dosomething } function oc(a) { var o = {}; for(var i=0;i<a.length;i++) o[a[i]]=''''; return o; }

por supuesto, como pueden ver, esto lleva las cosas un paso más allá y les facilita seguir la lógica.

snook.ca/archives/javascript/testing_for_a_v

usando operadores como ~ && || ((), ()) ~~ está bien solo si su código se rompe más adelante. No sabrá por dónde empezar. Entonces la legibilidad es GRANDE.

si debe, puede hacerlo más corto.

(''a'' in oc([''a'',''b'',''c''])) && statement; (''a'' in oc([''a'',''b'',''c''])) && (statements,statements); (''a'' in oc([''a'',''b'',''c'']))?statement:elseStatement; (''a'' in oc([''a'',''b'',''c'']))?(statements,statements):(elseStatements,elseStatements);

y si quieres hacer inversa

(''a'' in oc([''a'',''b'',''c''])) || statement;


Esto se puede resolver con un simple bucle for:

test = {}; test.type = ''itema''; for(var i=[''itema'',''itemb'',''itemc'']; i[0]==test.type && [ (function() { // do something console.log(''matched!''); })() ]; i.shift());

Usamos la primera sección del bucle for para inicializar los argumentos que desea hacer coincidir, la segunda sección para detener la ejecución del bucle for y la tercera sección para hacer que el bucle finalmente salga.


Excelentes respuestas, pero podrías hacer que el código sea mucho más legible si envuelves uno de ellos en una función.

Esta es una declaración compleja, cuando usted (u otra persona) lea el código en un período de años, estará escaneando para encontrar la sección para comprender lo que está sucediendo. Una declaración con este nivel de lógica de negocios hará que te tropieces durante unos segundos mientras trabajas en lo que estás probando. Donde un código como este, le permitirá continuar escaneando.

if(CheckIfBusinessRuleIsTrue()) { //Do Something } function CheckIfBusinessRuleIsTrue() { return (the best solution from previous posts here); }

Asigne un nombre a su función explícitamente para que sea obvio inmediatamente lo que está probando y su código será mucho más fácil de escanear y comprender.


Para facilitar la lectura, crea una función para la prueba (sí, una función de una línea):

function isTypeDefined(test) { return test.type == ''itema'' || test.type == ''itemb'' || test.type == ''itemc'' || test.type == ''itemd''; }

entonces llámalo:

… if (isTypeDefined(test)) { … } ...


Para largas listas de cadenas, esta idea ahorraría algunos caracteres (sin decir que lo recomendaría en la vida real, pero debería funcionar).

Elige un personaje que sabes que no ocurrirá en tu test.type, úsalo como un delimitador, pégalo todo en una cadena larga y busca eso:

if ("/itema/itemb/itemc/itemd/".indexOf("/"+test.type+"/")>=0) { // doSomething }

Si tus cadenas se ven aún más restringidas, incluso podrías omitir los delimitadores ...

if ("itemaitembitemcitemd".indexOf(test.type)>=0) { // doSomething }

... pero tendrías que tener cuidado con los falsos positivos en ese caso (por ejemplo, "embate" coincidiría en esa versión)


Podrías poner todas las respuestas en un conjunto de Javascript y luego simplemente llamar a .contains() en el conjunto.

Aún debe declarar todos los contenidos, pero la llamada en línea será más corta.

Algo como:

var itemSet = new Set(["itema","itemb","itemc","itemd"]); if( itemSet.contains( test.type ){}


Pon tus valores en una matriz y comprueba si tu elemento está en la matriz:

if ([1, 2, 3, 4].includes(test.type)) { // Do something }

Si un navegador que admite no tiene el método Array#includes , puede usar este polyfill .

Breve explicación del atajo de ~ tilde:

Actualización: dado que ahora tenemos el método de inclusión, ya no tiene sentido usar el ~ hack. Solo mantengo esto aquí para las personas que estén interesadas en saber cómo funciona y / o lo hayan encontrado en el código de otros.

En lugar de verificar si el resultado de indexOf es >= 0 , hay un pequeño y bonito atajo:

if ( ~[1, 2, 3, 4].indexOf(test.type) ) { // Do something }

Aquí está el violín: http://jsfiddle.net/HYJvK/

¿Como funciona esto? Si se encuentra un elemento en la matriz, indexOf devuelve su índice. Si el artículo no se encontró, devolverá -1 . Sin entrar en demasiados detalles, ~ es un operador NOT bit a bit , que devolverá 0 solo para -1 .

Me gusta usar el ~ atajo, ya que es más sucinto que hacer una comparación en el valor de retorno. Deseo que JavaScript tenga una función in_array que devuelva un Boolean directamente (similar a PHP), pero eso es solo una ilusión ( Actualización: ahora sí. Se llama includes . Ver arriba). Tenga en cuenta que jQuery''s inArray , aunque comparte la firma del método de PHP, en realidad imita la funcionalidad del indexOf nativo (que es útil en diferentes casos, si el índice es lo que verdaderamente desea).

Nota importante: el uso del atajo de tilde parece estar envuelto en controversia, ya que algunos creen vehementemente que el código no es lo suficientemente claro y debe evitarse a toda costa (ver los comentarios sobre esta respuesta). Si comparte su opinión, debe apegarse a la .indexOf(...) >= 0 .

Una pequeña explicación más larga:

Los enteros en JavaScript están firmados, lo que significa que el bit más a la izquierda está reservado como el bit de signo; una bandera para indicar si el número es positivo o negativo, con un 1 es negativo.

Estos son algunos ejemplos de números positivos en formato binario de 32 bits:

1 : 00000000000000000000000000000001 2 : 00000000000000000000000000000010 3 : 00000000000000000000000000000011 15: 00000000000000000000000000001111

Ahora aquí están esos mismos números, pero negativos:

-1 : 11111111111111111111111111111111 -2 : 11111111111111111111111111111110 -3 : 11111111111111111111111111111101 -15: 11111111111111111111111111110001

¿Por qué tales combinaciones extrañas para los números negativos? Sencillo. Un número negativo es simplemente el inverso del número positivo + 1; agregar el número negativo al número positivo siempre debe rendir 0 .

Para entender esto, hagamos una aritmética binaria simple.

Aquí es cómo agregaríamos -1 a +1 :

00000000000000000000000000000001 +1 + 11111111111111111111111111111111 -1 ------------------------------------------- = 00000000000000000000000000000000 0

Y aquí es cómo agregaríamos -15 a +15 :

00000000000000000000000000001111 +15 + 11111111111111111111111111110001 -15 -------------------------------------------- = 00000000000000000000000000000000 0

¿Cómo obtenemos esos resultados? Al hacer una adición regular, la forma en que nos enseñaron en la escuela: comienzas en la columna de la derecha y agregas todas las filas. Si la suma es mayor que el mayor número de un solo dígito (que en decimal es 9 , pero en binario es 1 ) llevamos el resto a la siguiente columna.

Ahora, como notará, al agregar un número negativo a su número positivo, la columna del extremo derecho que no es todos los 0 s siempre tendrá dos 1 s, que cuando se sumen juntos darán como resultado 2 . La representación binaria de dos es 10 , llevamos el 1 a la columna siguiente, y ponemos un 0 para el resultado en la primera columna. Todas las demás columnas a la izquierda tienen solo una fila con un 1 , por lo que el 1 transferido desde la columna anterior sumará nuevamente hasta 2 , que luego se transferirá ... Este proceso se repite hasta que llegamos a la izquierda columna, donde el 1 que se va a trasladar no tiene dónde ir, por lo que se desborda y se pierde, y nos quedamos con 0 s en todas partes.

Este sistema se llama Complemento 2 . Puedes leer más sobre esto aquí:

Representación del complemento de 2 para enteros con signo .

Ahora que el curso acelerado en el complemento 2 ha finalizado, observará que -1 es el único número cuya representación binaria tiene 1 ''s en todas partes.

Usando el operador NOT bit a bit, todos los bits en un número dado se invierten. La única manera de obtener 0 vuelta de invertir todos los bits es si comenzamos con 1 en todo.

Entonces, todo esto fue una manera larga de decir que ~n solo devolverá 0 si n es -1 .


Puede usar la instrucción switch con Fall Through:

switch (test.type) { case "itema": case "itemb": case "itemc": case "itemd": // do something }


Si está comparando con cadenas y hay un patrón, considere usar expresiones regulares.

De lo contrario, sospecho que intentar acortarlo solo ofuscará tu código. Considere simplemente envolver las líneas para hacerlo bonito.

if (test.type == ''itema'' || test.type == ''itemb'' || test.type == ''itemc'' || test.type == ''itemd'') { do something. }


Solo use una instrucción switch lugar de if :

switch (test.type) { case "itema":case "itemb":case "itemc":case "itemd": // do your process case "other cases":...: // do other processes default: // do processes when test.type does not meet your predictions. }

Switch también funciona más rápido que la comparación de muchos condicionales dentro de un if


Una de mis formas favoritas de lograr esto es con una biblioteca como underscore.js ...

var isItem = _.some([''itema'',''itemb'',''itemc'',''itemd''], function(item) { return test.type === item; }); if(isItem) { // One of them was true }

http://underscorejs.org/#some


Usando Science: debes hacer lo que dice idfah y esto para obtener la velocidad más rápida mientras mantienes corto el código:

ESTO ES MÁS RÁPIDO QUE ~ Método

var x = test.type; if (x == ''itema'' || x == ''itemb'' || x == ''itemc'' || x == ''itemd'') { //do something }

jsperf.com/if-statements-test-techsin (Conjunto superior: Chrome, conjunto inferior: Firefox)

Conclusión

Si las posibilidades son pocas y usted sabe que es más probable que ocurran ciertas, obtendrá el máximo rendimiento if || , el switch fall through , y if(obj[keyval]) .

Si las posibilidades son muchas , y cualquiera de ellas podría ser la que más se presenta, en otras palabras, no puede saber cuál es más probable que ocurra que obtener el máximo rendimiento de la búsqueda de objetos if(obj[keyval]) y regex si eso encaja.

http://jsperf.com/if-statements-test-techsin/12

Actualizaré si surge algo nuevo.


if( /^item[a-d]$/.test(test.type) ) { /* do something */ }

o si los artículos no son tan uniformes, entonces:

if( /^(itema|itemb|itemc|itemd)$/.test(test.type) ) { /* do something */ }


var possibilities = { "itema": 1, "itemb": 1, "itemc": 1, …}; if (test.type in possibilities) { … }

Usar un objeto como una matriz asociativa es algo muy común, pero como JavaScript no tiene un conjunto nativo, también puedes usar objetos como conjuntos baratos.