switch multiple es6 else ejemplos condicional javascript jquery comparison switch-statement

javascript - multiple - Declaración de cambio para mayor que/menor que



switch javascript ejemplos (10)

Odio usar 30 declaraciones if

Tuve la misma situación últimamente, así es como lo resolví:

antes de:

if(wind_speed >= 18) { scale = 5; } else if(wind_speed >= 12) { scale = 4; } else if(wind_speed >= 9) { scale = 3; } else if(wind_speed >= 6) { scale = 2; } else if(wind_speed >= 4) { scale = 1; }

después:

var scales = [[4, 1], [6, 2], [9, 3], [12, 4], [18, 5]]; scales.forEach(function(el){if(wind_speed > el[0]) scale = el[1]});

Y si configura "1, 2, 3, 4, 5", puede ser incluso más simple:

var scales = [4, 6, 9, 12, 18]; scales.forEach(function(el){if(wind_speed >= el) scale++});

así que quiero usar una declaración de cambio como esta:

switch (scrollLeft) { case (<1000): //do stuff break; case (>1000 && <2000): //do stuff break; }

Ahora sé que cualquiera de esas declaraciones ( <1000 ) o ( >1000 && <2000 ) no funcionará (por diferentes razones, obviamente). Lo que estoy preguntando es la forma más eficiente de hacerlo. Odio usar 30 declaraciones if , por lo que prefiero usar la sintaxis del interruptor. ¿Hay algo que pueda hacer?


¿Qué estás haciendo exactamente en //do stuff ?

Es posible que pueda hacer algo como:

(scrollLeft < 1000) ? //do stuff : (scrollLeft > 1000 && scrollLeft < 2000) ? //do stuff : (scrollLeft > 2000) ? //do stuff : //etc.


Actualizando la respuesta aceptada (aún no puedo comentar). A partir del 1/12/16 usando la demo jsfiddle en cromo, switch-immediate es la solución más rápida.

Resultados: resolución de tiempo: 1.33

25ms "if-immediate" 150878146 29ms "if-indirect" 150878146 24ms "switch-immediate" 150878146 128ms "switch-range" 150878146 45ms "switch-range2" 150878146 47ms "switch-indirect-array" 150878146 43ms "array-linear-switch" 150878146 72ms "array-binary-switch" 150878146

Terminado

1.04 ( 25ms) if-immediate 1.21 ( 29ms) if-indirect 1.00 ( 24ms) switch-immediate 5.33 ( 128ms) switch-range 1.88 ( 45ms) switch-range2 1.96 ( 47ms) switch-indirect-array 1.79 ( 43ms) array-linear-switch 3.00 ( 72ms) array-binary-switch


Cuando miré las soluciones en las otras respuestas, vi algunas cosas que sé que son malas para el rendimiento. Iba a ponerlos en un comentario, pero pensé que era mejor compararlo y compartir los resultados. Puedes probarlo tú mismo . Debajo están mis resultados (ymmv) normalizados después de la operación más rápida en cada navegador (multiplique el tiempo 1.0 con el valor normalizado para obtener el tiempo absoluto en ms).

Chrome Firefox Opera MSIE Safari Node ------------------------------------------------------------------- 1.0 time 37ms 73ms 68ms 184ms 73ms 21ms if-immediate 1.0 1.0 1.0 2.6 1.0 1.0 if-indirect 1.2 1.8 3.3 3.8 2.6 1.0 switch-immediate 2.0 1.1 2.0 1.0 2.8 1.3 switch-range 38.1 10.6 2.6 7.3 20.9 10.4 switch-range2 31.9 8.3 2.0 4.5 9.5 6.9 switch-indirect-array 35.2 9.6 4.2 5.5 10.7 8.6 array-linear-switch 3.6 4.1 4.5 10.0 4.7 2.7 array-binary-switch 7.8 6.7 9.5 16.0 15.0 4.9

Prueba donde se realizó en Windows 7 32 bits con las siguientes versiones: Chrome 21.0.1180.89m , Firefox 15.0 , Opera 12.02 , MSIE 9.0.8112 , Safari 5.1.7 . El nodo se ejecutó en un cuadro Linux de 64 bits porque la resolución del temporizador en Node.js para Windows fue de 10 ms en lugar de 1 ms.

si-inmediato

Este es el más rápido en todos los entornos probados, excepto en ... ¡ drumroll MSIE! (sorpresa sorpresa). Esta es la forma recomendada de implementarlo.

if (val < 1000) { /*do something */ } else if (val < 2000) { /*do something */ } else ... if (val < 30000) { /*do something */ } else

if-indirecto

Esta es una variante de switch-indirect-array pero con if states en su lugar y funciona mucho más rápido que switch-indirect-array en casi todos los entornos probados.

values=[ 1000, 2000, ... 30000 ]; if (val < values[0]) { /* do something */ } else if (val < values[1]) { /* do something */ } else ... if (val < values[29]) { /* do something */ } else

interruptor-inmediato

Esto es bastante rápido en todos los entornos probados, y en realidad es el más rápido en MSIE. Funciona cuando puede hacer un cálculo para obtener un índice.

switch (Math.floor(val/1000)) { case 0: /* do something */ break; case 1: /* do something */ break; ... case 29: /* do something */ break; }

rango de interruptores

Esto es aproximadamente de 6 a 40 veces más lento que el más rápido en todos los entornos probados, excepto en el caso de Opera, donde demora aproximadamente una vez y media. Es lento porque el motor tiene que comparar el valor dos veces para cada caso. Sorprendentemente, Chrome tarda casi 40 veces más en completar esto en comparación con la operación más rápida en Chrome, mientras que MSIE solo tarda 6 veces más. Pero la diferencia de tiempo real fue de solo 74ms a favor de MSIE a 1337ms (!).

switch (true) { case (0 <= val && val < 1000): /* do something */ break; case (1000 <= val && val < 2000): /* do something */ break; ... case (29000 <= val && val < 30000): /* do something */ break; }

switch-range2

Esta es una variante del switch-range de switch-range pero con solo una comparación por caso y, por lo tanto, más rápida, pero aún muy lenta, excepto en Opera. El orden de la declaración de caso es importante ya que el motor probará cada caso en el orden del código fuente ECMAScript262: 5 12.11

switch (true) { case (val < 1000): /* do something */ break; case (val < 2000): /* do something */ break; ... case (val < 30000): /* do something */ break; }

switch-indirect-array

En esta variante, los rangos se almacenan en una matriz. Esto es lento en todos los entornos probados y muy lento en Chrome.

values=[1000, 2000 ... 29000, 30000]; switch(true) { case (val < values[0]): /* do something */ break; case (val < values[1]): /* do something */ break; ... case (val < values[29]): /* do something */ break; }

array-linear-search

Esta es una combinación de una búsqueda lineal de valores en una matriz y la instrucción switch con valores fijos. La razón por la que uno querría usar esto es cuando los valores no se conocen hasta el tiempo de ejecución. Es lento en todos los entornos probados, y lleva casi 10 veces más tiempo en MSIE.

values=[1000, 2000 ... 29000, 30000]; for (sidx=0, slen=values.length; sidx < slen; ++sidx) { if (val < values[sidx]) break; } switch (sidx) { case 0: /* do something */ break; case 1: /* do something */ break; ... case 29: /* do something */ break; }

array-binary-switch

Esta es una variante de array-linear-switch pero con una búsqueda binaria. Desafortunadamente es más lento que la búsqueda lineal. No sé si es mi implementación o si la búsqueda lineal está más optimizada. También podría ser que el espacio de claves sea pequeño.

values=[0, 1000, 2000 ... 29000, 30000]; while(range) { range = Math.floor( (smax - smin) / 2 ); sidx = smin + range; if ( val < values[sidx] ) { smax = sidx; } else { smin = sidx; } } switch (sidx) { case 0: /* do something */ break; ... case 29: /* do something */ break; }

Conclusión

Si el rendimiento es importante, use if -statements o switch con valores inmediatos.


En mi caso (código de colores, un porcentaje, nada crítico para el rendimiento), rápidamente escribí esto:

function findColor(progress) { const thresholds = [30, 60]; const colors = ["#90B451", "#F9A92F", "#90B451"]; return colors.find((col, index) => { return index >= thresholds.length || progress < thresholds[index]; }); }


Esta es otra opción:

switch (true) { case (value > 100): //do stuff break; case (value <= 100)&&(value > 75): //do stuff break; case (value < 50): //do stuff break; }


No comprobado y no está seguro de si esto funcionará, pero ¿por qué no hacer algunas if statements antes? Para establecer variables para la switch statement .

var small, big; if(scrollLeft < 1000){ //add some token to the page //call it small } switch (//reference token/) { case (small): //do stuff break; case (big): //do stuff; break; }


Puede crear un objeto personalizado con los criterios y la función correspondiente a los criterios

var rules = [{ lowerLimit: 0, upperLimit: 1000, action: function1 }, { lowerLimit: 1000, upperLimit: 2000, action: function2 }, { lowerLimit: 2000, upperLimit: 3000, action: function3 }];

Defina funciones para lo que quiere hacer en estos casos (defina function1, function2, etc.)

Y "evaluar" las reglas

function applyRules(scrollLeft) { for(var i=0; i>rules.length; i++) { var oneRule = rules[i]; if(scrollLeft > oneRule.lowerLimit && scrollLeft < oneRule.upperLimit) { oneRule.action(); } } }

Nota

Odio usar 30 declaraciones if

Muchas veces si las declaraciones son más fáciles de leer y mantener. Recomendaría lo anterior solo cuando tenga muchas condiciones y una posibilidad de mucho crecimiento en el futuro.

Actualizar
Como @Brad señaló en los comentarios, si las condiciones son mutuamente excluyentes (solo una de ellas puede ser verdadera a la vez), verificar el límite superior debería ser suficiente:

if(scrollLeft < oneRule.upperLimit)

siempre que las condiciones se definan en orden ascendente (primero la más baja, de 0 to 1000 y luego de 1000 to 2000 por ejemplo)


Una alternativa:

var scrollleft = 1000; switch (true) { case (scrollleft > 1000): alert(''gt''); break; case (scrollleft <= 1000): alert(''lt''); break; }

Demostración: http://jsfiddle.net/UWYzr/


switch (scrollLeft/1000) { case 0: // (<1000) //do stuff break; case 1: // (>=1000 && <2000) //do stuff; break; }

Solo funciona si tienes pasos regulares ...

EDIT: dado que esta solución sigue recibiendo upvotes, debo avisar que la solución de mofolo es mucho mejor.