Existe uma maneira melhor de escrever v = (v == 0? 1: 0); [fechadas]


465

Quero alternar uma variável entre 0 e 1. Se for 0, quero configurá-lo para 1, caso contrário, se for 1, quero configurá-lo para 0.

Esta é uma operação tão fundamental que escrevo tantas vezes que gostaria de investigar a maneira mais curta e clara possível de fazê-lo. Aqui está o meu melhor até agora:

v = (v == 0 ? 1 : 0);

Você pode melhorar isso?

Edit: a pergunta é perguntar como escrever a declaração acima com o menor número de caracteres, mantendo a clareza - como isso não é uma pergunta real? Não era para ser um exercício de código-golfe, embora algumas respostas interessantes tenham surgido de pessoas que o abordam como golfe - é bom ver o golfe sendo usado de maneira construtiva e instigante.


20
Isso já parece simples / claro / curto para mim.
Mob

136
truques:v = +!v;
jAndy 2/08

48
Se 'melhor' também significa 'mais rápido': jsperf.com/v-0-1-0 .
Pimvdb

7
@Mobinga: +1. Isso é tão simples quanto deveria. Todas as outras respostas que vejo são confusas, e algumas delas mudam a lógica; introdução de bugs.
Ian Boyd

8
@holodoc Uma solução melhor para expressar sua opinião seria criar uma resposta que diga que você acha que o original é o melhor caminho e elabore por que você acha que esse é o caso. isso também permite que outras pessoas se apóiam facilmente na sua resposta votando nela.
Chuck van der Linden

Respostas:


721

Você pode simplesmente usar:

v = 1 - v;

Obviamente, isso pressupõe que a variável seja inicializada corretamente, ou seja, que ela tenha apenas o valor 0 ou 1.

Outro método que é mais curto, mas usa um operador menos comum:

v ^= 1;

Editar:

Para ser claro; Eu nunca abordei essa questão como código de golfe, apenas para encontrar uma maneira curta de executar a tarefa sem usar truques obscuros, como efeitos colaterais dos operadores.


206
São belas linhas de código, como vidro finamente cortado ou orquídeas raras. Adoro como você alcançou diretamente a camada lógica e lidou diretamente com a matemática de 1 e 0 com as operações mais ideais possíveis. Eu os usarei em meus próprios projetos, mas, infelizmente, quando eu precisar que o código seja entendido pelos colegas de trabalho, terei que adotar uma abordagem mais baseada em lógica. Obrigado, porém, sua resposta fez o meu dia.
Ollie Glass

37
Você sempre pode adicionar um comentário dizendo o que o código faz.
Prusse

25
@ Kevin: não é verdade que isso claramente não responde à pergunta, conforme solicitado. O q disse "eu quero alternar uma variável entre 0 e 1." Uma interpretação bastante razoável é que isso implica que o valor da variável já seja 0 ou 1. Essa interpretação / limitação foi explicitada na resposta. O que no mundo você pode se opor?
LarsH

50
@ Matthew para dizer que alguém que não acha v ^= 1claro deve parar de programar é um pouco severo, eu acho. Como afirmado anteriormente, não é um dos operadores mais comuns e não faz o mesmo que v = v ^ 1. Além disso, o operador significa algo completamente diferente em diferentes idiomas (VB). Sim, uma rápida pesquisa lhe dirá que é um operador XOR e você entenderá o que está fazendo, mas para muitos pode não ser óbvio à primeira vista. Eu não acho que isso significa que você precisa sair do seu emprego.
JD Isaacks #

80
Se você salvar 15 caracteres escrevendo isso, mas depois usar 40 caracteres para explicá-lo, será realmente uma melhoria?
Michael Myers

343

Uma vez que 0é um falsevalor e 1é um truevalor.

v = (v ? 0 : 1);

Se você está feliz em usar truee, em falsevez de números

v = !v;

ou se eles devem ser números:

v = +!v; /* Boolean invert v then cast back to a Number */

55
basta colocar a magia +antes disso !. Ohhh isso parece muuuuito sujo! mas legal: p
jAndy 2/11

1
@Quentin - isso vai quebrar o código do cara se ele tem switch(v){ case 0 ...ou se (v == 0) ou se v === 0. Você está mudando o seu resultado, além de sua abordagem ....
Brian

34
Faça um smiley do mesmo: ({v :+! v}).v.
Pimvdb

17
@ Brian: não com esse +sinal mágico ! ¯ \ _ (ツ) _ / ¯
Jandy

11
+1 para v = (v ? 0 : 1)JS claro e idiomático.
Bennett McElwee

200

v = (v + 1) % 2e se você precisa para percorrer mais valores apenas mudar 2para (n + 1). Digamos que você precise pedalar 0,1,2, apenas faça v = (v + 1) % 3.


2
Eu amo o ciclo! Isso é realmente inteligente.
Ollie Glass

16
+1 por pensar na alternância como um ciclo. Simples, considerando como é flexível.
Guffa 02/08/19

3
+1 por fornecer uma solução modular também robusta. Na prática, você provavelmente iria querer usar uma constvariável no lugar dos números mágicos 2, 3, ...
Oosterwal

2
Maneira mais curta (mais hackier): ++v % 3se você deseja percorrer 0, 1, 2
haraldmartin

75

Você pode escrever uma função para ela e usá-la como:

v = inv(v)


30
+1 Concordo plenamente esta é a solução mais limpa (... mas então o que se passa na invfunção: P)
Lea Hayes

4
Eu gostaria de poder dar a esta resposta mais do que apenas +1. Se o código comum não for ofuscantemente óbvio, ele deverá ser envolvido em uma função com um nome descritivo.
TehShrike

11
@TehShrike você considera invum nome descritivo?
Bennett McElwee

3
@Bennett McElwee: inv = inverter. Sempre pareceu uma abreviação comum para mim.
Daniel

51
Por que abreviá-lo, chame-o de 'inverter' ou 'alternar' e deixar o código legível. não é como se estivéssemos tentando encaixar essas coisas em um cartão perfurado de 80 colunas ou algo assim.
Chuck van der Linden

50

Se você não se importa com outra possibilidade além de 1:

v = v ? 0 : 1;

No caso acima, v acabará sendo 1 se v for 0, falso, indefinido ou nulo. Tome cuidado ao usar esse tipo de abordagem - v será 0 mesmo que v seja "olá mundo".


2
Isso não mudará o valor. Você quer dizer v = v ? 0 : 1.
Guffa 02/08/19

3
@Guffa - 1 para a captura de minha dislexia ...
Brian

3
Esta é minha resposta favorita baseada em lógica que posso usar com colegas de trabalho (estou vendo a resposta de @ Guffa como baseada em número). Gosto de como você fez o teste desnecessário (v == 0) e os colchetes, diminuindo-o para a contagem mínima absoluta de caracteres. Obrigado.
Ollie Glass

1
Eu sou um grande fã de resposta da @ Guffa também - nas palavras de Skynard Lynard, mantê-lo simples homem;)
Brian

2
+1 para entender os valores "verdadeiros".
precisa saber é o seguinte

44

Linhas como v = 1 - v, ou v ^= 1ou v= +!v, todas farão o trabalho, mas constituem o que eu chamaria de hacks. Essas não são belas linhas de código, mas truques baratos para obter o efeito pretendido. 1 - vnão se comunica "alterna o valor entre 0 e 1". Isso torna seu código menos expressivo e apresenta um local (ainda que pequeno) onde outro desenvolvedor precisará analisar seu código.

Ter, em vez disso, uma função como v = toggle(v)comunica a intenção à primeira vista.


8
-1, sério, v=1-vnão comunica a alternância?
Blindy 02/08/19

22
1-vpode se comunicar de fato alternar, mas é a única coisa que se comunica. Por exemplo, ele também pode comunicar uma linha com zero em v=1ou uma transformação de espelhamento centrada em v=0.5. Nesse sentido, é relativamente ambíguo. É verdade que saber que vsó pode ser 0ou 1limitar seu significado pretendido, mas que força outros desenvolvedores (ou o seu eu futuro) a entender esse contexto antes de poder entender essa linha simples. Você não pode ser muito mais clara do quev = toggle(v)
Ray

10
v ^= 1é perfeitamente claro se você entende as operações lógicas, o que você tinha melhor se fosse um programador. Eu acho que essa é a diferença entre isso e v=1-v; uma é uma operação lógica e outra é uma operação aritmética, e estamos tentando representar um conceito lógico, não matemático.
Matthew Leia

6
@ Matthew Read: Esta é uma ótima declaração, que resume bem meus pensamentos: "estamos tentando representar um conceito lógico e não matemático". Mesmo v ^= 1tem alguma ambiguidade, no entanto, como pode ser interpretado como um xor bit a bit.
Ray

6
para programadores (e sim, quero dizer geeks como nós), isso é bem claro. Eles não são hacks, porque são soluções elegantes devido à sua simplicidade.
01

38

( Honestidade e integridade matemática - dado o número de votos nesta "resposta" - levaram-me a editar essa resposta. Esperei o máximo possível, porque ela pretendia ser uma piada curta e não como algo "profundo", para qualquer explicação parecia contrária ao objetivo. No entanto, os comentários estão deixando claro que devo ficar claro para evitar mal-entendidos. )

Minha resposta original:

O texto desta parte da especificação:

Se for 0, quero defini-lo como 1, caso contrário, defina-o como 0.

implica que a solução mais precisa é:

v = dirac_delta(0,v)

Em primeiro lugar, a confissão: eu queria chegar em minhas funções delta confuso. O delta do Kronecker teria sido um pouco mais apropriado, mas não tanto quanto eu queria algo independente do domínio (o delta do Kronecker é usado principalmente apenas para números inteiros). Mas eu realmente não deveria ter usado funções delta, eu deveria ter dito:

v = characteristic_function({0},v)

Deixe-me esclarecer. Recorde-se que uma função é um triplo, (X, Y, F) , em que X e Y são grupos (o chamado domínio e codomain respectivamente) e f é um regra que atribui um elemento de Y para cada elemento de X . Muitas vezes escrever o triplo (X, Y, f) como f: X → Y . Dado um subconjunto de X , digamos A , existe uma função característica que é uma função χ A : X → {0,1}(também pode ser pensado como uma função para um codomain maior, como ℕ ou ℝ). Esta função é definida pela regra:

χ A (x) = 1 , se x ∈ A e χ A (x) = 0 se x ∉ Uma .

Se você gosta de tabelas verdade, é a tabela verdade para a pergunta "O elemento x de X é um elemento do subconjunto A ?".

Portanto, a partir dessa definição, fica claro que a função característica é o que é necessário aqui, com X um grande conjunto contendo 0 e A = {0} . Isso é o que eu deveria ter escrito.

E assim, para funções delta. Para isso, precisamos saber sobre integração. Ou você já sabe ou não. Caso contrário, nada do que eu possa dizer aqui irá falar sobre os meandros da teoria, mas posso dar um resumo de uma frase. Uma medida em um conjunto X é essencialmente "aquilo que é necessário para fazer as médias funcionarem". Isto é, se tivermos um conjunto X e uma medida μ nesse conjunto, haverá uma classe de funções X → ℝ , denominada funções mensuráveis para as quais a expressão X f dμ faz sentido e, em algum sentido vago, a "média" de f sobre X .

Dada uma medida em um conjunto, pode-se definir uma "medida" para subconjuntos desse conjunto. Isso é feito atribuindo a um subconjunto a integral de sua função característica (assumindo que essa seja uma função mensurável). Isso pode ser infinito ou indefinido (os dois são sutilmente diferentes).

Existem muitas medidas por aí, mas há duas que são importantes aqui. Uma é a medida padrão na linha real, ℝ. Para esta medida, então f dμ é praticamente o que se ensina na escola (é cálculo ainda ensinada nas escolas?): Soma-se pequenos retângulos e tomar larguras menores e menores. Nesta medida, a medida de um intervalo é sua largura. A medida de um ponto é 0.

Outra medida importante, que funciona em qualquer conjunto, é chamada de medida pontual . É definido para que a integral de uma função seja a soma de seus valores:

X f dμ = ∑ x fX f (x)

Essa medida atribui a cada conjunto singleton a medida 1. Isso significa que um subconjunto possui uma medida finita se e somente se ela própria é finita. E muito poucas funções têm integral finito. Se uma função tem uma integral finita, ela deve ser diferente de zero apenas em um número contável de pontos. Portanto, a grande maioria das funções que você provavelmente conhece não possui integral finita sob essa medida.

E agora para funções delta. Vamos dar uma definição muito ampla. Temos um espaço mensurável (X, μ) (de modo que é um conjunto com uma medida sobre ele) e um elemento a ∈ X . "Definimos" a função delta (dependendo de a ) para ser a "função" δ a : X → ℝ com a propriedade que δ a (x) = 0 se x ≠ a e X δ a dμ = 1 .

O fato mais importante sobre isso para se manter em contato é o seguinte: A função delta não precisa ser uma função . É não corretamente definido: Eu não disse que ô um (a) é.

O que você faz neste momento depende de quem você é. O mundo aqui se divide em duas categorias. Se você é matemático, diz o seguinte:

Ok, então a função delta pode não estar definida. Vamos dar uma olhada em suas propriedades hipotéticas e ver se podemos encontrar um lar adequado para onde é definido. Podemos fazer isso e terminamos com distribuições . Essas não são (necessariamente) funções, mas são coisas que se comportam um pouco como funções, e geralmente podemos trabalhar com elas como se fossem funções; mas há certas coisas que eles não têm (como "valores"), por isso precisamos ter cuidado.

Se você não é um matemático, diz o seguinte:

Ok, então a função delta pode não estar definida corretamente. Quem diz isso? Um monte de matemáticos? Ignore-os! O que eles sabem?

Tendo agora ofendido meu público, continuarei.

O dirac delta geralmente é considerado a função delta de um ponto (geralmente 0) na linha real com sua medida padrão. Portanto, aqueles que estão reclamando nos comentários sobre eu não conhecer meus deltas estão fazendo isso porque estão usando essa definição. Para eles, peço desculpas: embora eu possa me esquivar disso usando a defesa do matemático (como popularizada por Humpty Dumpty : simplesmente redefina tudo para que esteja correto), é uma má forma usar um termo padrão para significar algo diferente.

Mas não é uma função delta que faz o que eu quero fazer e é isso que eu preciso aqui. Se eu tomar uma medida de ponto em um conjunto X , então não é uma função genuína δ um : X → ℝ que satisfaça os critérios de uma função delta. Isto é porque nós estamos olhando para uma função X → ℝ que é zero, exceto em um e tal que a soma de todos os seus valores é 1. função Tal é simples: a peça faltando apenas de informação é o seu valor em um , e para que a soma seja 1, apenas atribuímos o valor 1. Isso não é outro senão a função característica em {a} . Então:

X δ a dμ = ∑ x ∈ X δ a (x) = δ a (a) = 1.

Portanto, neste caso, para um conjunto de singleton, a função característica e a função delta concordam.

Em conclusão, existem três famílias de "funções" aqui:

  1. As funções características de conjuntos singleton,
  2. As funções delta,
  3. O delta do Kronecker funciona.

O segundo deles é o mais geral, já que qualquer um dos outros é um exemplo disso ao usar a medida pontual. Mas o primeiro e o terceiro têm a vantagem de serem sempre funções genuínas. O terceiro, na verdade, é um caso especial do primeiro, para uma família específica de domínios (números inteiros ou algum subconjunto deles).

Então, finalmente, quando escrevi a resposta originalmente, não estava pensando direito (não diria que estava confuso , pois espero ter demonstrado que sei o que estou falando quando Na verdade, penso primeiro, não pensei muito). O significado usual do delta dirac não é o que se quer aqui, mas um dos pontos da minha resposta foi que o domínio de entrada não foi definido, de modo que o delta Kronecker também não estaria certo. Assim, a melhor resposta matemática (que eu estava buscando) teria sido a função característica .

Espero que tudo esteja claro; e também espero que nunca precise escrever uma peça matemática novamente usando entidades HTML em vez de macros TeX!


37
+1 - Se eu pudesse dar um voto negativo ao Quentin por não saber a função dirac_delta, eu o faria. Gostaria de saber para qual faculdade ele estudou, porque acho que não contrataria ninguém de lá se eles nem soubessem algo tão fundamental para o processamento digital. Eu rebaixaria ainda mais Quentin por sua incapacidade de entender o pouco de humor que você estava tentando.
Dunk

23
Se eu diminuísse o voto de todas as respostas que não entendia ... diminuiria o número de respostas.
Seamus

4
Olá Andrew, já faz um tempo.
Tim Baixo

4
@ Tim: Bom sofrimento, por isso tem! E como está o bispo das Bermudas? (Lembrei-me disso, certo?) Acho que esse tópico de comentários não é o melhor lugar para conversar, mas ... 17 anos, não é?
Andrew Stacey

3
@ Cԃ ա ԃ "Esta resposta falhou ..." suspiro . Você leu que eu sou um matemático, não leu? Essa resposta funciona perfeitamente para um programador esférico no vácuo, então não sei do que você está reclamando.
Andrew Stacey

35

Você poderia fazer

v = Math.abs(--v);

O decremento define o valor como 0 ou -1 e depois Math.absconverte -1 em +1.


27
Isso se transformou em uma competição 'Gerar 10000 maneiras de executar uma tarefa simples'. E eu gosto de todas as maneiras haha.
21413 Josh

27
v = Math.round(Math.sin(Math.PI/(v+3)));
Benoit

15
@Benoit - sua fórmula é igual a 1 para v = 0 e v = 1. Este aqui está correto! v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));: D
Teo.sk

2
Isso nunca mudaria o valor. Se v = 1então, v = Math.Abs(-1)qual é +1. Se v = 0então v = Math.Abs(-0)é 0.
Paul

1
+1 E este foi o meu outro ... Grr.
recursivo

34

em geral, sempre que você precisar alternar entre dois valores, basta subtrair o valor atual da soma dos dois valores de alternância:

    0,1 -> v = 1 - v
    1,2 -> v = 3 - v
    4,5 -> v = 9 - v 

2
Isso é interessante e criativo, mas potencialmente perigoso. Se vficar corrompido, subitamente começará a alternar entre dois valores diferentes. (Só uma coisa a considerar ...)
Oosterwal

1
+1 para a ideia interessante. não que o OP ou qualquer outra pessoa vá usá-lo nessas circunstâncias, mas essa informação deve existir em algum lugar do cérebro para sempre.
Shimmy Weitzhandler

3
@oosterwal: Então, certamente, o problema está na corrupção ...
GManNickG

@GManNickG: Mais cedo ou mais tarde, a corrupção de dados ocorrerá; portanto, precisamos estar cientes das consequências de não detectá-las. Se vnormalmente é usado para executar alternadamente dois estados de uma lista de três ou mais estados, uma corrupção de vpode fazer com que o programa execute alternadamente dois estados completamente diferentes - isso pode resultar em resultados inesperados e indesejáveis. A lição a ser tirada disso é: sempre realize verificações de plausibilidade nos seus dados.
27512 oosterwal

33

Se deve ser o número inteiro 1 ou 0, a maneira como você faz isso é boa, embora parênteses não sejam necessários. Se estes a forem usados ​​como booleanos, você poderá:

v = !v;

10
esse resultado no "v" de Ollie não será definido como um resultado booleano, e não como um número inteiro?
Brian

12
Sim, e eu avisei isso na frase acima da linha de código. Se estes um está a ser utilizado como booleans
Michael Berkowski

23
v = v == 0 ? 1 : 0;

Basta !


7
Mais uma opinião do que uma resposta, você não acha?
Brian

16
@ Brian: 'melhor' é tudo sobre opinião, na verdade.
Pimvdb

3
Gosto de como você tirou os parênteses - isso apara alguns caracteres!
Ollie Glass

9
@ Brian: A " resposta " é "Não, não há uma maneira melhor de escrever v = (v==0 ? 1 : 0);" . Todo mundo está encontrando maneiras diferentes de jogar golfe; e realmente não respondendo a pergunta. É por isso que votei positivamente nesta resposta.
Ian Boyd

19

Lista de soluções

Gostaria de propor três soluções. Todos eles converter qualquer valor para 0(se 1, trueetc.) ou 1(se 0, false, nulletc.):

  • v = 1*!v
  • v = +!v
  • v = ~~!v

e um adicional, já mencionado, mas inteligente e rápido (embora funcione apenas para 0s e 1s):

  • v = 1-v

Solução 1

Você pode usar a seguinte solução:

v = 1*!v

Isso primeiro converterá o número inteiro para o valor booleano oposto ( 0para Truee qualquer outro valor para False) e, em seguida, o tratará como número inteiro ao multiplicar por 1. Como resultado 0, será convertido para 1e qualquer outro valor para 0.

Como prova, veja este jsfiddle e forneça os valores que você deseja testar: jsfiddle.net/rH3g5/

Os resultados são os seguintes:

  • -123irá converter para inteiro 0,
  • -10irá converter para inteiro 0,
  • -1irá converter para inteiro 0,
  • 0irá converter para inteiro 1,
  • 1irá converter para inteiro 0,
  • 2irá converter para inteiro 0,
  • 60irá converter para inteiro 0,

Solução 2

Como mblase75 observou, o jAndy tinha outra solução que funciona como a minha:

v = +!v

Também primeiro torna booleano a partir do valor original, mas usa em +vez de 1*convertê-lo em número inteiro. O resultado é exatamente o mesmo, mas a notação é mais curta.

Solução 3

A outra abordagem é usar o ~~operador:

v = ~~!v

É bastante incomum e sempre converte em número inteiro a partir de booleano.


Em JavaScript, você pode prefixar uma variável com +para convertê-la em um número, o que +!vequivale à sua solução (solução de jAndy nos comentários do OP).
Blazemonger 14/10

@ mblase75: Sim, você está certo que 1*pode ser substituído +ao tentar converter booleano em número inteiro. Tudo o resto na minha resposta permanece o mesmo. A resposta de jAndy está correta, mas a minha é mais detalhada. Vou adicionar sua solução à minha resposta.
Tadeck 15/10

@Tadeck +1 para a boa ideia.
Shimmy Weitzhandler

17

Para resumir outra resposta, um comentário e minha própria opinião, sugiro combinar duas coisas:

  1. Use uma função para alternar
  2. Dentro desta função, use uma implementação mais legível

Aqui está a função que você pode colocar em uma biblioteca ou talvez envolvê-lo em um plug-in para outro framework Javascript.

function inv(i) {
  if (i == 0) {
    return 1
  } else {
    return 0;
  }
}

E o uso é simplesmente:

v = inv(v);

As vantagens são:

  1. Duplicação sem código
  2. Se você ou alguém ler isso novamente no futuro, entenderá seu código em um período mínimo de tempo.

São eles? Fiz um teste rápido: jsperf.com/function-vs-no-function/2 e parece que a diferença não é tanta.
Martin Schlagnitweit 2/08

25
7.5ns vs 8.8ns. Esses 1,3 nanossegundos extras vão realmente te matar.
22611 Ian Boyd

5
Com todo o tempo que economizei, levei minha família para a Disney World! :-)
Tom

1
Totalmente correto. Pessoas que escrevem soluções "inteligentes" provavelmente nunca tinham de manter outras "pérolas" de código de programadores
Avi

1
por que não function toggle(i){ return i == 0 ? 1 : 0 }?
Billy Lua

13

Não sei por que você quer construir seus próprios booleanos? Gosto das sintaxes descoladas, mas por que não escrever código compreensível?

Este não é o mais curto / mais rápido, mas o mais claro (e legível para todos) está usando o conhecido se / else estado:

if (v === 0)
{
  v = 1;
}
else
{
  v = 0;
}

Se você quiser ser realmente claro, use booleanos em vez de números para isso. Eles são rápidos o suficiente para a maioria dos casos. Com os booleanos, você pode usar esta sintaxe, que vencerá em pouco tempo:

v = !v;

1
Essa seria realmente a minha resposta preferida; mas operador ternário vs if-else é uma guerra santa que eu não queria acender o fusível. Dito isto, acho que a primeira linha deve ser === 0. Com a entrada de amostra de 7, a saída correta é 0, mas isso será gerado 1.
Ian Boyd

4
Existe valor em corrigir silenciosamente uma entrada como 7 em vez de lançar uma exceção de algum tipo? Quero dizer, e se algum outro pedaço de código tivesse as mãos no 7 quando esperava apenas 0 ou 1, antes que seu código corrigisse o valor?
Chuck van der Linden

12

Outra forma de sua solução original:

v = Number(v == 0);

Edição: Obrigado TehShrike e Guffa por apontar o erro na minha solução original.


4
O operador == retorna um booleano (em vez de um número inteiro) em muitos sistemas. Isso funcionaria apenas se v fosse definido como um número inteiro e o idioma fosse legal com a conversão automática de booleano para inteiro.
TehShrike

Muito verdadeiro. Eu estava respondendo a pergunta no contexto de javascript (como a pergunta foi marcada).
Kurt Kaylor #

@Kurt Kaylor: Javascript é um dos sistemas em que o operador == retorna um booleano, portanto não faz o mesmo que a solução original.
Guffa 03/08/19

@ Guffa: Estou aproveitando o fato de que o javascript é uma linguagem de tipo fraco com conversão implícita de tipos (por exemplo, '00.0000' == 0, 0 == "", false == "", false == 0, 1 == verdade, etc). Posso usar o valor booleano retornado da mesma maneira que posso usar um número inteiro de valor 0 ou 1. Tente, por exemplo, avaliar "2 + true" em um console javascript, você obterá 3.
Kurt Kaylor

1
@ Kurt Kaylor: Isso só funciona em situações em que você força uma conversão implícita. Tente, por exemplo, 'opacity:'+truee você acaba com, em opacity:truevez de opacity:1.
Guffa 3/08

11

Eu o tornaria mais explícito.

O que vsignifica isso ?

Por exemplo, quando v é algum estado. Crie um objeto Status. No DDD, um objeto de valor.

Implemente a lógica nesse objeto de valor. Então você pode escrever seu código de uma maneira mais funcional e mais legível. O status da troca pode ser feito criando um novo status com base no status atual. Sua instrução if / lógica é então encapsulada em seu objeto, que você pode unittest. Um valueObject é sempre imutável, portanto, não tem identidade. Então, para mudar seu valor, você precisa criar um novo.

Exemplo:

public class Status
{
    private readonly int _actualValue;
    public Status(int value)
    {
        _actualValue = value;
    }
    public Status(Status status)
    {
        _actualValue = status._actualValue == 0 ? 1 : 0; 
    }

    //some equals method to compare two Status objects
}

var status = new Status(0);

Status = new Status(status);

6
sobre engenharia?
Alejandro5042

6
+1 por me fazer rir
Denshi


10

Está faltando:

v = [1, 0][v];

Também funciona como rodízio:

v = [2, 0, 1][v]; // 0 2 1 0 ...
v = [1, 2, 0][v]; // 0 1 2 0 ...
v = [1, 2, 3, 4, 5, 0][v]; // 0 1 2 3 4 5 ...
v = [5, 0, 1, 2, 3, 4][v]; // 0 5 4 3 2 1 0 ...

Ou

v = {0: 1, 1: 0}[v];

O charme da última solução, também funciona com todos os outros valores.

v = {777: 'seven', 'seven': 777}[v];

Para um caso muito especial, gostaria de obter um valor (em mudança) e undefined, esse padrão pode ser útil:

v = { undefined: someValue }[v]; // undefined someValue undefined someValue undefined ...

9

Como esse é o JavaScript, podemos usar o unário +para converter em int:

v = +!v;

Isso lógico NOTo valor de v(fornecendo truese v == 0ou falsese v == 1). Em seguida, convertemos o valor booleano retornado em sua representação inteira correspondente.


8

Apenas para chutes: v = Math.pow(v-1,v)também alterna entre 1 e 0.


7

Mais um: v=++v%2

(em C seria simples ++v%=2)

ps. Sim, eu sei que é atribuição dupla, mas isso é apenas uma reescrita bruta do método C (que não funciona como está, porque o operador de pré-incremento JS não retorna lvalue.


3
Sua versão C é ilegal; você não pode modificar o resultado de um ++operador (não é um valor l). Quanto a v=++v%2, você está modificando vduas vezes. Não sei se isso está bem definido no JavaScript, mas não é necessário. v = (v+1) % 2.
amigos estão dizendo sobre keith thompson

Pelo menos c++está - porque o operador de pré-incremento tem prioridade mais alta e modifica a variável 'in place', para que possa ser usada como lvalue. Eu acho que a implementação de JS ++é tal que não pode ser tratada como um valor l: / E sim, isso é redundante, mas eu estava tentando mostrar apenas outro método - já existem soluções melhores :) :)
Adam Jurczyk

3
+1. Pode ser escrito como v = (v + 1)% 2.
Niktrs 03/08/19

7

Se você está garantido que sua entrada é 1 ou 0, então você pode usar:

v = 2+~v;

7

defina uma matriz {1,0}, defina v como v [v]; portanto, v com o valor 0 se tornará 1 e vica versa.


Minha solução está correta, se você não gostar, escreva o motivo. Seu comentário não ajuda ninguém. Minha solução lê uma variável, em vez de tomar uma decisão. Isso requer menos CPU.
S ..

5

Outra maneira criativa de fazer isso, vsendo igual a qualquer valor, sempre retornará 0ou1

v = !!v^1;

3
dois !!resultam em nada em matemática lógicos, você pode colocar !!!!lá e será mesmas, mas resultantes 4 operações unneed
Alex K

10
@ Alex: !!será convertido em um bool. !!(1) === truee!!(0) === false
nickf

1
@nickf: aha, então eu acho que v = Boolean(v^1)seria mais informativa, obrigado por explicar - não pensou sobre o elenco
Alex K

1
@ Alex, "matemática lógica"? É por isso que os matemáticos são maus programadores. Não me interpretem mal; bons programadores também são bons em entender matemática. Mas isso não tem nada a ver com matemática lógica. É uma construção de linguagem que, dada qualquer expressão, pelo menos em Javascript, !a converterá em booleana. Adicionar outro !negará esse valor booleano. A conversão está implícita aqui e o resultado final funciona. Não há necessidade do -1.
perfil completo de Yanick Rochon

1
eu não sou um matemático. você pode tentar fazer isso e se ver jsperf.com/javascript-boolean-test #
Alex K

4

Se os valores possíveis para v forem apenas 0 e 1, para qualquer número inteiro x, a expressão: v = Math.pow ((Math.pow (x, v) - x), v); irá alternar o valor.

Sei que essa é uma solução feia e o OP não estava procurando por isso ... mas estava pensando em outra solução quando estava no banheiro: P



3
v=!v;

funcionará para v = 0 e v = 1; e alternar o estado;


1

Se houver apenas dois valores, como neste caso (0, 1), acredito que seja um desperdício usar int. Em vez disso, escolha boolean e trabalhe em bits. Eu sei que estou assumindo, mas no caso de alternar entre dois estados booleanos parece ser a escolha ideal.


1

Bem, como sabemos que em javascript, apenas essa comparação booleana também fornecerá o resultado esperado.

ie v = v == 0 é suficiente para isso.

Abaixo está o código para isso:

var v = 0;
alert("if v  is 0 output: " + (v == 0));

setTimeout(function() {
  v = 1;
  alert("if v  is 1 Output: " + (v == 0));
}, 1000);

JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/

Esperando que isso ajude você :)


Isso funciona para alternar um valor, mas o valor não alterna entre 0 e 1, mas entre truee false. Você pode usar v == 0para determinar o valor da variável em uma condição, mas se desejar usar o valor 0 ou 1, precisará usar algo como v == 0 ? 0 : 1ou Number(v)obter isso. (Além disso, você pode v = !v;alternar entre truee false.)
Guffa 04/10

sim entendi .. obrigado :) #
1100 Vikash Pandey

0

v = Número (! v)

Ele digitará o valor booleano invertido para Number, que é a saída desejada.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.