Por ejemplo, algo como esto:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
¿Existe una mejor manera de escribir eso? Nuevamente, no estoy buscando una respuesta a la pregunta exacta anterior, solo un ejemplo de cuándo podría tener operandos repetidos en expresiones de operador ternario ...
javascript
conditional-operator
usuario1354934
fuente
fuente
if
y no anif/else
just an example of when you might have repeated things in the ternary
no repita expresiones calculadas. Para eso son las variables.3
no está en el índice0
desomeArray
?Math.max(someArray.indexOf(3), 0)
en su lugar?Respuestas:
Personalmente, encuentro que la mejor manera de hacer esto sigue siendo la vieja
if
declaración:fuente
if
declaración en lugar de un ternario. Las declaraciones ternarias siguen siendo útiles con frecuencia para realizar una elección como parte de una expresión.value
después de la primera línea es intermedio. No contiene el valor correcto que luego se fija en la siguiente línea y, por lo tanto, es un intermedio. Es solo después de que laif
declaración concluye quevalue
contiene el valor correcto. El ternario en el OP es una mejor solución que este porque nunca entra en un estado intermedio.value
aquí está técnicamente mutado, lo cual trato de evitar.El código debe ser legible, por lo que ser conciso no debe significar ser conciso sea cual sea el costo, para eso debe volver a publicar en https://codegolf.stackexchange.com/ , por lo que recomendaría usar una segunda variable local nombrada
index
para maximizar la comprensión de lectura ( con un costo mínimo de tiempo de ejecución también, observo):Pero si realmente desea reducir esta expresión, porque es un sádico cruel con sus compañeros de trabajo o colaboradores del proyecto, aquí hay 4 enfoques que puede usar:
1: variable temporal en una
var
declaraciónPuede usar la
var
capacidad de la declaración para definir (y asignar) una segunda variable temporalindex
cuando se separa con comas:2: función anónima autoejecutable
Otra opción es una función anónima autoejecutable:
3: operador de coma
También está el infame "operador de coma" que admite JavaScript, que también está presente en C y C ++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Puede usarlo para introducir efectos secundarios, en este caso reasignándolo a
value
:Esto funciona porque
var value
se interpreta primero (como una declaración), y luego el más a la izquierda, el más internovalue
asignación , y luego la parte derecha del operador de coma, y luego el operador ternario, todo JavaScript legal.4: reasignar en una subexpresión
El comentarista @IllusiveBrian señaló que el uso del operador de coma (en el ejemplo anterior) no es necesario si la asignación a
value
se usa como una subexpresión entre paréntesis:Tenga en cuenta que el uso de negativos en expresiones lógicas puede ser más difícil de seguir para los humanos, por lo que todos los ejemplos anteriores se pueden simplificar para su lectura cambiando
idx !== -1 ? x : y
aidx == -1 ? y : x
:fuente
indefOf
)var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
lugar de usar una coma.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
porque es solo un parámetro.Para números
Puede utilizar la
Math.max()
función.Mantendrá los límites del resultado
0
hasta el primer resultado mayor que0
si ese fuera el caso. Y si el resultado deindexOf
es-1
devolverá 0 ya que es mayor que-1
.Para valores booleanos y booleanos-y
Para JS no hay una regla general AFAIK especialmente porque cuán falsa valores .
Pero si algo puede ayudarte la mayor parte del tiempo es el operador or (
||
):Tienes que tener mucho cuidado con esto, porque en tu primer ejemplo,
indexOf
puede regresar0
y si lo evalúas0 || -1
regresará-1
porque0
es un valor falso .fuente
3
o"y"
no está en el índice0
desomeArray
?Math.max
ejemplo?indexOf
devuelve el índice del elemento y, si el elemento no se encuentra, devuelve -1, por lo que tiene una posibilidad de obtener un número de -1 a la longitud de la cadena, luegoMath.max
, simplemente establezca los límites de 0 a la longitud para eliminar la posibilidad para devolver un -1,0
del elemento coincidente dentro de la matriz, o0
establecido enMath.max()
; o en el operador condicional en OP. Considerevar value = Math.max( ["y"].indexOf("y"), 0 )
. ¿Cómo se determina cuál0
se devuelve?0
pasado paraMath.max()
llamar, o0
índice reflectante de"y"
dentro de la matriz?En realidad no, solo usa otra variable.
Tu ejemplo se generaliza a algo como esto.
Está probando un valor calculado y luego asigna ese valor a una variable si pasa algún predicado. La forma de evitar volver a calcular el valor calculado es obvia: utilice una variable para almacenar el resultado.
Entiendo lo que quieres decir: parece que debería haber alguna forma de hacer esto que se vea un poco más limpia. Pero creo que esa es la mejor manera (idiomáticamente) de hacer esto. Si estuviera repitiendo mucho este patrón en su código por alguna razón, podría escribir una pequeña función auxiliar:
fuente
EDITAR: ¡Aquí está, la propuesta de fusión de Nullary ahora en JavaScript!
Utilizar
||
const result = a ? a : 'fallback value';
es equivalente a
const result = a || 'fallback value';
Si se lanza
a
aBoolean
devolucionesfalse
,result
se le asignará'fallback value'
, de lo contrario el valor dea
.Tenga en cuenta el caso de borde
a === 0
, que se lanzafalse
yresult
tomará (incorrectamente)'fallback value'
. Utilice trucos como este bajo su propio riesgo.PD. Los lenguajes como Swift tienen un operador de fusión nula (
??
), que tiene un propósito similar. Por ejemplo, en Swift escribiría loresult = a ?? "fallback value"
que está bastante cerca de JavaScriptconst result = a || 'fallback value';
fuente
indexOf()
no se puede usar en este patrón.||
funciona JavaScript? Si lo entiendo correctamente, entonces funciona de manera diferente a muchos otros lenguajes primarios (estoy pensando principalmente en C y sus descendientes [C ++, Java, etc.]). Incluso si eso es realmente como||
funciona en JavaScript, desaconsejaría usar trucos como este que requieren que los mantenedores conozcan peculiaridades especiales del idioma. Si bien ese truco es genial, lo consideraría una mala práctica.-1
. Nuevamente, no puedo hablar por JavaScript y sus peculiaridades, pero en general-1
sería un valor verdadero, no falso, y por lo tanto su respuesta no funcionaría en el caso de la pregunta y ciertamente no en el caso general, sino que funcionaría solo en un ( pero bastante común) sub-caso.Utilice una refactorización de variables de extracción :
Es incluso mejor con en
const
lugar devar
. También puede hacer una extracción adicional:En la práctica, utilizar nombres más significativos que
index
,condition
, yvalue
.fuente
Probablemente esté buscando un operador coalescente. Afortunadamente, podemos aprovechar el
Array
prototipo para crear uno:Esto podría generalizarse aún más a su caso, agregando un parámetro a la función:
fuente
for (let x in ['b','c']) console.log(x);
impresiones0
,1
,"coalesce"
.Yo personalmente prefiero dos variantes:
Puro si, como sugirió @slebetman
Función separada, que reemplaza el valor no válido con uno predeterminado, como en este ejemplo:
fuente
Me gusta la respuesta de @ slebetman. El comentario debajo expresa preocupación acerca de que la variable esté en un "estado intermedio". si esto es una gran preocupación para usted, le sugiero encapsularlo en una función:
Entonces solo llama
Podrías hacer funciones más genéricas si tienes usos para ellas en otros lugares, pero no sobredimensiones si se trata de un caso muy específico.
Pero para ser honesto, solo haría como @slebetman a menos que necesite reutilizarlo desde varios lugares.
fuente
Hay dos formas en las que puedo ver su pregunta: desea reducir la longitud de la línea o desea evitar específicamente la repetición de una variable en un ternario. El primero es trivial (y muchos otros usuarios han publicado ejemplos):
puede ser (y debería ser, dadas las llamadas de función) acortado así:
Si está buscando una solución más genérica que evite la repetición de una variable en un ternario, así:
donde
foo
solo aparece una vez. Descartando soluciones de la forma:como técnicamente correcto pero sin entender, entonces no tienes suerte. Hay operadores, funciones y métodos que poseen la sintaxis concisa que busca, pero tales construcciones, por definición, no son operadores ternarios .
Ejemplos:
javascript, usando
||
para devolver el RHS cuando el LHS esfalsey
:fuente
Utilice una función auxiliar:
Ahora su código es muy legible y no hay repetición.
La jerarquía de preocupaciones de codificación es:
Todas las respuestas en la página hasta ahora parecen ser correctas, pero creo que mi versión tiene la mayor claridad, que es más importante que la concisión. Si no cuenta la función auxiliar, ya que puede reutilizarse, también es la más concisa. La sugerencia algo similar de usar una función de ayuda desafortunadamente usa una lambda que, para mí, simplemente oscurece lo que está haciendo. Una función más simple con un propósito que no toma una lambda, solo valores, es para mí mucho mejor.
PD: si te gusta la sintaxis de ES6:
fuente
translateValueIfEqual
que pensé que era más descriptivo, pero lo cambié después de que alguien pensó que era demasiado largo. Al igual que laNz
función en Access, si la conoce, la conoce, y si no la conoce, no la conoce. En los IDE modernos, puede simplemente presionar una tecla para saltar a la definición. Y la alternativa sería la variable intermedia. Realmente no veo un gran inconveniente aquí.Creo que el
||
operador se puede adaptar aindexOf
:El valor devuelto se desplaza hacia arriba en 1, haciendo 0 de -1, que es falso y, por lo tanto, se reemplaza por el segundo 1. Luego se desplaza hacia atrás.
Sin embargo, tenga en cuenta que la legibilidad es superior a evitar la repetición.
fuente
Esta es una solución simple con NOT bit a bit y un valor predeterminado
-1
cuyo resultado más tarde es cero.Funciona básicamente con un NOT doble bit a bit, que devuelve el valor original o un valor predeterminado, que después de aplicar NOT bit a bit devuelve cero.
Echemos un vistazo a la tabla de la verdad:
fuente
Podría usar la reasignación:
&&
operador para la reasignación, porque si la primera condición es falsa, la segunda expresión no se evaluaráEx.
Mostrar fragmento de código
fuente
someArray.indexOf
solo se realiza una vezvalue
.-1
y0
; de lo contrariomax()
, sería la mejor opciónAgain, not seeking an answer to the exact question above
, lo que deja la pregunta a la interpretación;)Dado el código de ejemplo en la pregunta, no está claro cómo se determinaría si
3
se establece o no en el índice0
desomeArray
.-1
devuelto de.indexOf()
sería valioso en este caso, con el propósito de excluir una supuesta no coincidencia que podría ser una coincidencia.Si
3
no está incluido en la matriz,-1
se devolverá. Podemos agregar1
al resultado de.indexOf()
para evaluar comofalse
resultado-1
, donde seguido del||
OR
operador y0
. Cuandovalue
se hace referencia, reste1
para obtener el índice del elemento de la matriz o-1
.Lo que nos lleva a simplemente usar
.indexOf()
y verificar-1
unaif
condición. O, definiendovalue
comoundefined
para evitar una posible confusión en cuanto al resultado real de la condición evaluada en relación con la referencia original.fuente
Un ternario es como un if-else, si no necesitas la parte else, ¿por qué no solo un if?
fuente
Para este caso particular, podría utilizar un cortocircuito con el
||
operador lógico . Como0
se considera falso, puede agregar1
a su índice, por lo tanto, siindex+1
es0
, obtendrá el lado derecho del lógico, o como resultado, de lo contrario, obtendrá suindex+1
. Como el resultado deseado se compensa con1
, luego puede restarlo1
para obtener su índice:fuente