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.
javascript
variables
coding-style
toggle
Ollie Glass
fonte
fonte
v = +!v;
Respostas:
Você pode simplesmente usar:
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:
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.
fonte
v ^= 1
claro 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 quev = 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.Uma vez que
0
é umfalse
valor e1
é umtrue
valor.Se você está feliz em usar
true
e, emfalse
vez de númerosou se eles devem ser números:
fonte
+
antes disso!
. Ohhh isso parece muuuuito sujo! mas legal: pswitch(v){ case 0 ...
ou se (v == 0) ou se v === 0. Você está mudando o seu resultado, além de sua abordagem ....({v :+! v}).v
.+
sinal mágico ! ¯ \ _ (ツ) _ / ¯v = (v ? 0 : 1)
JS claro e idiomático.v = (v + 1) % 2
e se você precisa para percorrer mais valores apenas mudar2
para(n + 1)
. Digamos que você precise pedalar 0,1,2, apenas façav = (v + 1) % 3
.fonte
const
variável no lugar dos números mágicos 2, 3, ...++v % 3
se você deseja percorrer 0, 1, 2Você pode escrever uma função para ela e usá-la como:
v = inv(v)
fonte
inv
função: P)inv
um nome descritivo?Se você não se importa com outra possibilidade além de 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".
fonte
v = v ? 0 : 1
.Linhas como
v = 1 - v
, ouv ^= 1
ouv= +!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 - v
nã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.fonte
v=1-v
não comunica a alternância?1-v
pode se comunicar de fato alternar, mas é a única coisa que se comunica. Por exemplo, ele também pode comunicar uma linha com zero emv=1
ou uma transformação de espelhamento centrada emv=0.5
. Nesse sentido, é relativamente ambíguo. É verdade que saber quev
só pode ser0
ou1
limitar 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)
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 ev=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.v ^= 1
tem alguma ambiguidade, no entanto, como pode ser interpretado como um xor bit a bit.( 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:
implica que a solução mais precisa é:
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:
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:
Se você não é um matemático, diz o seguinte:
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:
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!
fonte
Você poderia fazer
O decremento define o valor como 0 ou -1 e depois
Math.abs
converte -1 em +1.fonte
v = Math.round(Math.sin(Math.PI/(v+3)));
v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));
: Dv = 1
então,v = Math.Abs(-1)
qual é +1. Sev = 0
entãov = Math.Abs(-0)
é 0.em geral, sempre que você precisar alternar entre dois valores, basta subtrair o valor atual da soma dos dois valores de alternância:
fonte
v
ficar corrompido, subitamente começará a alternar entre dois valores diferentes. (Só uma coisa a considerar ...)v
normalmente é usado para executar alternadamente dois estados de uma lista de três ou mais estados, uma corrupção dev
pode 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.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á:
fonte
Basta !
fonte
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.Lista de soluções
Gostaria de propor três soluções. Todos eles converter qualquer valor para
0
(se1
,true
etc.) ou1
(se0
,false
,null
etc.):v = 1*!v
v = +!v
v = ~~!v
e um adicional, já mencionado, mas inteligente e rápido (embora funcione apenas para
0
s e1
s):v = 1-v
Solução 1
Você pode usar a seguinte solução:
Isso primeiro converterá o número inteiro para o valor booleano oposto (
0
paraTrue
e qualquer outro valor paraFalse
) e, em seguida, o tratará como número inteiro ao multiplicar por1
. Como resultado0
, será convertido para1
e qualquer outro valor para0
.Como prova, veja este jsfiddle e forneça os valores que você deseja testar: jsfiddle.net/rH3g5/
Os resultados são os seguintes:
-123
irá converter para inteiro0
,-10
irá converter para inteiro0
,-1
irá converter para inteiro0
,0
irá converter para inteiro1
,1
irá converter para inteiro0
,2
irá converter para inteiro0
,60
irá converter para inteiro0
,Solução 2
Como mblase75 observou, o jAndy tinha outra solução que funciona como a minha:
Também primeiro torna booleano a partir do valor original, mas usa em
+
vez de1*
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:É bastante incomum e sempre converte em número inteiro a partir de booleano.
fonte
+
para convertê-la em um número, o que+!v
equivale à sua solução (solução de jAndy nos comentários do OP).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.Para resumir outra resposta, um comentário e minha própria opinião, sugiro combinar duas coisas:
Aqui está a função que você pode colocar em uma biblioteca ou talvez envolvê-lo em um plug-in para outro framework Javascript.
E o uso é simplesmente:
As vantagens são:
fonte
function toggle(i){ return i == 0 ? 1 : 0 }
?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:
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:
fonte
=== 0
. Com a entrada de amostra de7
, a saída correta é0
, mas isso será gerado1
.Outra forma de sua solução original:
Edição: Obrigado TehShrike e Guffa por apontar o erro na minha solução original.
fonte
'opacity:'+true
e você acaba com, emopacity:true
vez deopacity:1
.Eu o tornaria mais explícito.
O que
v
significa 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:
fonte
Outra maneira de fazer isso:
fonte
Está faltando:
Também funciona como rodízio:
Ou
O charme da última solução, também funciona com todos os outros valores.
Para um caso muito especial, gostaria de obter um valor (em mudança) e
undefined
, esse padrão pode ser útil:fonte
Como esse é o JavaScript, podemos usar o unário
+
para converter em int:Isso lógico
NOT
o valor dev
(fornecendotrue
sev == 0
oufalse
sev == 1
). Em seguida, convertemos o valor booleano retornado em sua representação inteira correspondente.fonte
Apenas para chutes:
v = Math.pow(v-1,v)
também alterna entre 1 e 0.fonte
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.
fonte
++
operador (não é um valor l). Quanto av=++v%2
, você está modificandov
duas vezes. Não sei se isso está bem definido no JavaScript, mas não é necessário.v = (v+1) % 2
.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 :) :)Se você está garantido que sua entrada é 1 ou 0, então você pode usar:
fonte
defina uma matriz {1,0}, defina v como v [v]; portanto, v com o valor 0 se tornará 1 e vica versa.
fonte
Outra maneira criativa de fazer isso,
v
sendo igual a qualquer valor, sempre retornará0
ou1
fonte
!!
resultam em nada em matemática lógicos, você pode colocar!!!!
lá e será mesmas, mas resultantes 4 operações unneed!!
será convertido em um bool.!!(1) === true
e!!(0) === false
v = Boolean(v^1)
seria mais informativa, obrigado por explicar - não pensou sobre o elenco!
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.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
fonte
Não testado, mas se você estiver atrás de um booleano, acho
var v = !v
que funcionará.Referência: http://www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables
fonte
funcionará para v = 0 e v = 1; e alternar o estado;
fonte
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.
fonte
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:
JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/
Esperando que isso ajude você :)
fonte
true
efalse
. Você pode usarv == 0
para determinar o valor da variável em uma condição, mas se desejar usar o valor 0 ou 1, precisará usar algo comov == 0 ? 0 : 1
ouNumber(v)
obter isso. (Além disso, você podev = !v;
alternar entretrue
efalse
.)Ele digitará o valor booleano invertido para Number, que é a saída desejada.
fonte