Siempre me han enseñado que tener efectos secundarios en una if
afección es malo. Lo que quiero decir es;
if (conditionThenHandle()) {
// do effectively nothing
}
... Opuesto a;
if (condition()) {
handle();
}
... y entiendo eso, y mis colegas están contentos porque no lo hago, y todos nos vamos a casa a las 17:00 un viernes y todos tienen un feliz fin de semana.
Ahora, ECMAScript5 introdujo métodos como every()
y some()
to Array
, y los encuentro muy útiles. Son más limpios que for (;;;)
los demás, le dan otro alcance y hacen que el elemento sea accesible mediante una variable.
Sin embargo, al validar la entrada, casi siempre me encuentro usando every
/ some
en la condición para validar la entrada, luego uso every
/ some
nuevamente en el cuerpo para convertir la entrada en un modelo utilizable;
if (input.every(function (that) {
return typeof that === "number";
})) {
input.every(function (that) {
// Model.findById(that); etc
}
} else {
return;
}
... cuando lo que quiero hacer es;
if (!input.every(function (that) {
var res = typeof that === "number";
if (res) {
// Model.findById(that); etc.
}
return res;
})) {
return;
}
... lo que me da efectos secundarios en una if
condición que es mala.
En comparación, este es el código con un viejo for (;;;)
;
for (var i=0;i<input.length;i++) {
var curr = input[i];
if (typeof curr === "number") {
return;
}
// Model.findById(curr); etc.
}
Mis preguntas son:
- ¿Es definitivamente una mala práctica?
- ¿Estoy (mis | ab) usando
some
yevery
(¿ debería estar usando afor(;;;)
para esto?) - ¿Hay un mejor enfoque?
fuente
some
, quiero hacer algo con el elemento, si lo usoevery
, quiero hacer algo a todos esos elementos ...some
yevery
no me dejen acceder a esa información, así que tampoco puedo los uso, o tengo que agregar efectos secundarios.some
en miif
condición para determinar si un determinado elemento de la matriz exhibe una cierta propiedad, 9/10 necesito para operar en ese elemento en miif
cuerpo; ahora, comosome
no me dice cuál de los elementos exhibió la propiedad (solo "uno lo hizo"), puedo usarlosome
nuevamente en el cuerpo (O (2n)), o simplemente puedo realizar la operación dentro de la condición if ( lo cual es malo, porque es un efecto secundario dentro de la cabeza).every
también, por supuesto.Respuestas:
Si entiendo su punto correctamente, usted parece ser mis-consumo o abuso
every
ysome
pero es un poco inevitable si desea cambiar los elementos de las matrices directamente. Corrígeme si me equivoco, pero lo que intentas hacer es averiguar si alguno o todos los elementos de tu secuencia exhiben una determinada condición y luego modificar esos elementos. Además, su código parece estar aplicando algo a todos los elementos hasta que encuentre uno que no pase el predicado y no creo que sea lo que quiera hacer. De todos modosTomemos su primer ejemplo (ligeramente modificado)
Lo que estás haciendo aquí en realidad va un poco en contra del espíritu de algunos / todos / mapas / reducir / filtrar / etc.conceptos.
Every
no debe usarse para afectar a todos los elementos que se ajustan a algo, sino que solo debe usarse para decirle si cada elemento de una colección lo hace. Si desea aplicar una función a todos los elementos para los que un predicado se evalúa como verdadero, la forma "buena" de hacerlo esAlternativamente, puede usar en
foreach
lugar de mapa para modificar los elementos en el lugar.La misma lógica se aplica
some
básicamente a:every
para probar si todos los elementos de una matriz pasan alguna prueba.some
para probar si al menos un elemento de una matriz pasa alguna prueba.map
para devolver una nueva matriz que contiene 1 elemento (que es el resultado de una función de su elección) para cada elemento en una matriz de entrada.filter
para devolver una matriz de longitud 0 <length
<initial array length
elementos, todos contenidos en la matriz original y todo pasar la prueba predicado suministrado.foreach
si quieres un mapa pero en el lugarreduce
si desea combinar los resultados de una matriz en un solo resultado de objeto (que podría ser una matriz pero no tiene que ser así).Cuanto más los use (y más escriba el código LISP), más se dará cuenta de cómo están relacionados e incluso es posible emular / implementar uno con los demás. Lo que es poderoso con estas consultas y lo que es realmente interesante es su semántica y cómo realmente lo empujan a eliminar los efectos secundarios dañinos en su código.
EDITAR (a la luz de los comentarios): Entonces, supongamos que desea validar que cada elemento es un objeto y convertirlos en un Modelo de aplicación si todos son válidos. Una forma de hacer esto en una sola pasada sería:
De esta manera, cuando un objeto no pasa la validación, aún sigue iterando a través de toda la matriz, lo que sería más lento que simplemente validar con
every
. Sin embargo, la mayoría de las veces su matriz será válida (o eso espero), por lo que en la mayoría de los casos realizará una sola pasada sobre su matriz y terminará con una matriz utilizable de objetos del Modelo de aplicación. Se respetará la semántica, se evitarán los efectos secundarios y todos estarán felices.Tenga en cuenta que también podría escribir su propia consulta, similar a foreach, que aplicaría una función a todos los miembros de una matriz y devolverá verdadero / falso si todos pasan una prueba de predicado. Algo como:
Aunque eso modificaría la matriz en su lugar.
Espero que esto ayude, fue muy divertido escribir. ¡Salud!
fuente
if (input.every())
, para verificar que cada elemento sea un objeto (typeof el === "object && el !== null
), etc., luego , si eso valida, quiero convertir cada elemento en el respectivo modelo de aplicación (que, ahora mencionasmap()
, podría usarinput.map(function (el) { return new Model(el); });
; pero no necesariamente en su lugar .)map()
tener que iterar sobre la matriz dos veces; una para validar y otra para convertir. Sin embargo, utilizando un estándar defor(;;;)
bucle, que podía hacer esto utilizando una iteración, pero no puedo encontrar una manera de aplicarevery
,some
,map
ofilter
, en este escenario, y realizar sólo un paso, sin tener-secundarios indeseados efectos o la introducción de otro modo mal- práctica.Los efectos secundarios no están en la condición if, están en el cuerpo del if. Solo ha determinado si ejecutar o no ese cuerpo en la condición real. No hay nada malo con su enfoque aquí.
fuente
if
condición, con solo elreturn
ser dentro delif
cuerpo; obviamente estoy hablando de la muestra de código precedida por " lo que quiero hacer es ...if
condición.