entonces 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 pregunto es la forma más eficiente de hacer precisamente eso. Odio usar 30 if
declaraciones, así que prefiero usar la sintaxis de cambio. ¿Hay algo que pueda hacer?
your_mapper_object[scrollLeft / SOME_CONST]
, suponiendo queyour_mapper_object
sea algo así{1: some_func, 2: another_func, ...}
. Y en este caso también podría usar el interruptor.Respuestas:
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 . A continuación se muestran 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).
La prueba se realizó en Windows 7 de 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 . Node se ejecutó en una caja 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 es 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.
si indirecto
Esta es una variante de
switch-indirect-array
pero conif
declaraciones en su lugar y funciona mucho más rápido queswitch-indirect-array
en casi todos los entornos probados.cambio 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.
rango de conmutación
Esto es aproximadamente de 6 a 40 veces más lento que el más rápido en todos los entornos probados, excepto Opera, donde dura aproximadamente una vez y media más. 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 74 ms a favor de MSIE a 1337 ms (!).
switch-range2
Esta es una variante 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 del caso es importante ya que el motor probará cada caso en el orden del código fuente ECMAScript262: 5 12.11conmutador-matriz-indirecta
En esta variante, los rangos se almacenan en una matriz. Esto es lento en todos los entornos probados y muy lento en Chrome.
array-linear-search
Esta es una combinación de una búsqueda lineal de valores en una matriz y la instrucción de cambio con valores fijos. La razón por la que uno podría querer usar esto es cuando los valores no se conocen hasta el tiempo de ejecución. Es lento en todos los entornos probados y tarda casi 10 veces más en MSIE.
matriz-interruptor-binario
Esta es una variante de
array-linear-switch
pero con una búsqueda binaria. Lamentablemente 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 teclas sea demasiado pequeño.Conclusión
Si el rendimiento es importante, use
if
declaraciones oswitch
con valores inmediatos.fuente
Una alternativa:
Demostración: http://jsfiddle.net/UWYzr/
fuente
if(...) else if(...)
? Esto sí lo evita,if
pero no me parece un buen reemplazo.if
declaraciones. Vea mi respuesta aquíSolo funciona si tienes pasos regulares ...
EDITAR: dado que esta solución sigue recibiendo votos positivos, debo advertir que la solución de mofolo es mucho mejor
fuente
Math.round(scrollLeft/1000)
por cierto.Puede crear un objeto personalizado con los criterios y la función correspondiente a los criterios.
Defina funciones para lo que desea hacer en estos casos (defina function1, function2, etc.)
Y "evaluar" las reglas
Nota
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.
Actualización
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:
siempre que las condiciones se definan en orden ascendente (primero la más baja
0 to 1000
, y luego,1000 to 2000
por ejemplo)fuente
action=function1
¿No deberían ser estos dos puntos? ;-) - También puede refactorizar esto para que solo tenga un límite superior ya que, debido al proceso de eliminación, no puede caer dentro de dos grupos, a menos que sea su intención (tener múltiples acciones posibles).¿Qué estás haciendo exactamente
//do stuff
?Es posible que pueda hacer algo como:
fuente
No probado e inseguro si esto funcionará, pero ¿por qué no hacer algunos
if statements
antes, para establecer variables para elswitch statement
.fuente
Esta es otra opción:
fuente
Actualizando la respuesta aceptada (no puedo comentar aún). A partir del 1/12/16 con la demo jsfiddle en Chrome, switch-inmediato es la solución más rápida.
Resultados: Resolución de tiempo: 1.33
Terminado
fuente
En mi caso (codificación por colores de un porcentaje, nada crítico para el rendimiento), rápidamente escribí esto:
fuente
Tuve la misma situación últimamente, así es como lo resolví:
antes de:
después:
Y si configura "1, 2, 3, 4, 5", entonces puede ser aún más simple:
fuente