Por exemplo, algo assim:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Existe uma maneira melhor de escrever isso? Novamente, não estou procurando uma resposta para a pergunta exata acima, apenas um exemplo de quando você pode ter operandos repetidos em expressões de operador ternário ...
javascript
conditional-operator
usuário1354934
fonte
fonte
if
e não umif/else
just an example of when you might have repeated things in the ternary
não repita expressões calculadas. É para isso que servem as variáveis.3
não está no índice0
desomeArray
?Math.max(someArray.indexOf(3), 0)
?Respostas:
Pessoalmente, acho que a melhor maneira de fazer isso ainda é a boa e velha
if
declaração:fonte
if
instrução no lugar de um ternário. As declarações ternárias ainda são frequentemente úteis para realizar uma escolha como parte de uma expressão.value
após a primeira linha é intermediário. Ele não contém o valor correto que é então fixado na próxima linha e, portanto, é um intermediário. É somente após aif
conclusão da instrução quevalue
contém o valor correto. O ternário no OP é uma solução melhor que este porque nunca entra em um estado intermediário.value
aqui está tecnicamente mutado, o que tento evitar.O código deve ser legível, portanto, ser sucinto não deve significar ser conciso custe o que custar - para isso, você deve reenviar para https://codegolf.stackexchange.com/ - então, em vez disso, eu recomendaria usar uma segunda variável local chamada
index
para maximizar a compreensão de leitura ( com custo mínimo de tempo de execução também, eu observo):Mas se você realmente deseja reduzir essa expressão, porque você é um sádico cruel com seus colegas de trabalho ou colaboradores do projeto, então aqui estão 4 abordagens que você pode usar:
1: Variável temporária em uma
var
declaraçãoVocê pode usar a
var
capacidade da instrução para definir (e atribuir) uma segunda variável temporáriaindex
quando separada por vírgulas:2: Função anônima autoexecutável
Outra opção é uma função anônima autoexecutável:
3: operador vírgula
Há também o infame "operador de vírgula" que o JavaScript suporta, que também está presente em C e C ++.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Você pode usá-lo para introduzir efeitos colaterais, neste caso, reatribuindo a
value
:Isso funciona porque
var value
é interpretado primeiro (como se fosse uma instrução) e, em seguida , avalue
atribuição mais à esquerda, mais interna , e então à direita do operador vírgula e, em seguida, o operador ternário - todo JavaScript válido.4: Reatribuir em uma subexpressão
O comentador @IllusiveBrian apontou que o uso do operador vírgula (no exemplo anterior) é desnecessário se a atribuição a
value
for usada como uma subexpressão entre parênteses:Observe que o uso de negativos em expressões lógicas pode ser mais difícil para humanos seguirem - portanto, todos os exemplos acima podem ser simplificados para leitura mudando
idx !== -1 ? x : y
paraidx == -1 ? y : x
:fonte
indefOf
)var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
vez de usar uma vírgula.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
porque é apenas um parâmetro.Para números
Você pode usar a
Math.max()
função.Isso manterá os limites do resultado
0
até o primeiro resultado maiores do que0
se for esse o caso. E se o resultado deindexOf
for,-1
ele retornará 0, pois é maior que-1
.Para valores booleanos e booleanos
Para JS, não há regra geral AFAIK, especialmente porque os valores falsos são avaliados.
Mas se algo pode ajudá-lo na maioria das vezes é o operador ou (
||
):Você tem que ter muito cuidado com isso, pois no seu primeiro exemplo,
indexOf
pode retornar0
e se avaliar0 || -1
retornará-1
porque0
é um valor falso .fonte
3
ou"y"
não está no índice0
desomeArray
?Math.max
exemplo?indexOf
retorna o índice do elemento e se o elemento não for encontrado retorna -1 então você tem uma chance de obter um número de -1 ao comprimento da string então comMath.max
você apenas defina os limites de 0 ao comprimento para remover a chance para retornar a -1,0
do elemento correspondente na matriz ou0
definido comoMath.max()
; ou no operador condicional no OP. Considerevar value = Math.max( ["y"].indexOf("y"), 0 )
. Como você determina o que0
está sendo devolvido?0
passado paraMath.max()
chamar, ou0
refletindo o índice de"y"
dentro da matriz?Não realmente, apenas use outra variável.
Seu exemplo se generaliza para algo assim.
Você está testando um valor calculado e, em seguida, atribuindo esse valor a uma variável se ela passar algum predicado. A maneira de evitar o recálculo do valor calculado é óbvia: use uma variável para armazenar o resultado.
Entendi o que você quis dizer - parece que deve haver alguma maneira de fazer isso que pareça um pouco mais limpa. Mas acho que essa é a melhor maneira (linguística) de fazer isso. Se você estiver repetindo muito esse padrão em seu código por algum motivo, poderá escrever uma pequena função auxiliar:
fonte
EDIT: Aqui está, a proposta de coalescência nular agora em JavaScript!
Usar
||
const result = a ? a : 'fallback value';
é equivalente a
const result = a || 'fallback value';
Se lançar
a
paraBoolean
retornafalse
,result
será atribuído'fallback value'
, caso contrário, o valor dea
.Esteja ciente do caso extremo
a === 0
, que lança parafalse
eresult
irá (incorretamente) levar'fallback value'
. Use truques como este por sua própria conta e risco.PS. Linguagens como Swift têm operador de coalescência nil (
??
), que serve a um propósito semelhante. Por exemplo, em Swift você escreveria oresult = a ?? "fallback value"
que é muito próximo do JavaScriptconst result = a || 'fallback value';
fonte
indexOf()
não pode ser usado neste padrão.||
funciona em JavaScript? Se estou entendendo você corretamente, então funciona diferente de muitas outras linguagens primárias (estou pensando principalmente em C e seus descendentes [C ++, Java, etc.]) Mesmo que seja realmente assim que||
funciona em JavaScript, eu desaconselho o uso truques como esse que exigem que os mantenedores conheçam peculiaridades da linguagem. Embora esse truque seja legal, eu consideraria uma prática ruim.-1
. Novamente, não posso falar em JavaScript e suas peculiaridades, mas geralmente-1
seria um valor verdadeiro, não falso e, portanto, sua resposta não funcionaria no caso da pergunta e certamente não no caso geral, ao invés disso, funcionaria apenas em um caso específico ( mas bastante comum) sub-caso.Use uma refatoração de variável de extração :
É ainda melhor com em
const
vez devar
. Você também pode fazer uma extração adicional:Na prática, usar nomes mais significativos do que
index
,condition
evalue
.fonte
Você provavelmente está procurando um operador de coalescência. Felizmente, podemos aproveitar o
Array
protótipo para criar um:Isso poderia ser generalizado para o seu caso, adicionando um parâmetro à função:
fonte
for (let x in ['b','c']) console.log(x);
gravuras0
,1
,"coalesce"
.Eu pessoalmente prefiro duas variantes:
Puro se, como @slebetman sugeriu
Função separada, que substitui o valor inválido pelo padrão, como neste exemplo:
fonte
Eu gosto da resposta de @ slebetman. O comentário abaixo expressa preocupação sobre a variável estar em um "estado intermediário". se isso é uma grande preocupação para você, sugiro encapsulá-lo em uma função:
Então é só ligar
Você poderia fazer funções mais genéricas se tiver usos para elas em outros lugares, mas não faça engenharia excessiva se for um caso muito específico.
Mas para ser honesto, eu faria apenas como @slebetman, a menos que precisasse reutilizar em vários lugares.
fonte
Há duas maneiras de ver sua pergunta: ou você deseja reduzir o comprimento da linha ou deseja evitar especificamente a repetição de uma variável em um ternário. O primeiro é trivial (e muitos outros usuários postaram exemplos):
pode ser (e deve ser, dadas as chamadas de função) encurtado assim:
Se você está procurando uma solução mais genérica que evite a repetição de uma variável em um ternário, assim:
onde
foo
aparece apenas uma vez. Descartando soluções do formulário:como tecnicamente correto, mas perdendo o ponto, você está sem sorte. Existem operadores, funções e métodos que possuem a sintaxe concisa que você procura, mas tais construções, por definição, não são operadores ternários .
Exemplos:
javascript, usando
||
para retornar o RHS quando o LHS éfalsey
:fonte
Use uma função auxiliar:
Agora seu código é muito legível e não há repetição.
A hierarquia de interesses de codificação é:
Todas as respostas da página até agora parecem corretas, mas acho que minha versão tem a maior clareza, o que é mais importante do que a concisão. Se você não contar a função auxiliar, pois ela pode ser reutilizada, ela também é a mais concisa. A sugestão um tanto semelhante de usar uma função auxiliar infelizmente usa um lambda que, para mim, apenas obscurece o que está fazendo. Uma função mais simples com um propósito que não leva lambda, apenas valores, é muito melhor para mim.
PS Se você gosta da sintaxe ES6:
fonte
translateValueIfEqual
que eu achei mais descritivo, mas mudei depois que alguém achou que era muito longo. Muito parecido com aNz
função no Access, se você conhece, você sabe, e se não conhece, você não conhece. Em IDEs modernos, você pode simplesmente pressionar uma tecla para pular para a definição. E o fallback seria a variável intermediária. Eu realmente não vejo um grande lado negativo aqui.Acho que o
||
operador pode ser adaptado paraindexOf
:O valor retornado é deslocado para cima em 1, tornando 0 de -1, que é falsey e, portanto, é substituído pelo segundo 1. Em seguida, ele é deslocado de volta.
No entanto, lembre-se de que a legibilidade é superior a evitar a repetição.
fonte
Esta é uma solução simples com NOT bit a bit e um valor padrão de
-1
que resulta posteriormente em zero.Funciona basicamente com um NOT bit a bit duplo, que retorna o valor original ou um valor padrão, que após aplicar o NOT bit a bit retorna zero.
Vamos dar uma olhada na tabela da verdade:
fonte
Você pode usar a reatribuição:
&&
operador para reatribuição, pois se a primeira condição for falsa, a segunda expressão não será avaliadaEx.
Exibir trecho de código
fonte
someArray.indexOf
é executada apenas uma vezvalue
.-1
e0
; caso contrário,max()
seria a melhor opçãoAgain, not seeking an answer to the exact question above
, o que deixa a questão para interpretação;)Dado o código de exemplo em Question, não está claro como seria determinado se
3
é ou não definido no índice0
desomeArray
.-1
retornado de.indexOf()
seria valioso neste caso, com o propósito de excluir uma não correspondência presumida que poderia ser uma correspondência.Se
3
não estiver incluído na matriz,-1
será retornado. Podemos adicionar1
ao resultado de.indexOf()
avaliar comofalse
sendo o resultado-1
, onde seguido pelo||
OR
operador e0
. Quandovalue
é referenciado, subtraia1
para obter o índice do elemento da matriz ou-1
.O que leva de volta a simplesmente usar
.indexOf()
e verificar-1
umaif
condição. Ou, definindovalue
comoundefined
para evitar possível confusão quanto ao resultado real da condição avaliada relativa a referência original.fonte
Um ternário é como um if-else, se você não precisa da parte else, por que não apenas um único if.
fonte
Para este caso específico, você pode usar o curto-circuito com o
||
operador lógico . Como0
é considerado falso, você pode adicionar1
ao seu índice, portanto, seindex+1
for0
, você obterá o lado direito da lógica - ou como resultado, caso contrário, obterá o seuindex+1
. Como o resultado desejado é compensado por1
, você pode subtrair1
dele para obter seu índice:fonte