Esiste un modo migliore di scrivere v = (v == 0? 1: 0); [chiuso]


465

Voglio alternare una variabile tra 0 e 1. Se è 0, voglio impostarlo su 1, altrimenti se è 1, voglio impostarlo su 0.

Questa è un'operazione così fondamentale che scrivo così spesso che vorrei indagare sul modo più breve e chiaro possibile di farlo. Ecco il mio meglio finora:

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

Puoi migliorare su questo?

Modifica: la domanda è: come scrivere la frase sopra nel minor numero di caratteri, pur mantenendo la chiarezza: in che modo questa "non è una vera domanda"? Questo non era inteso come un esercizio di code-golf, anche se alcune risposte interessanti sono venute da persone che si avvicinavano al golf: è bello vedere il golf essere usato in modo costruttivo e stimolante.


20
Questo mi sembra già semplice / chiaro / breve.
Mob

136
inganno:v = +!v;
jAndy

48
Se "migliore" significa anche "più veloce": jsperf.com/v-0-1-0 .
pimvdb,

7
@Mobinga: +1. Questo è semplice come dovrebbe ottenere. Tutte le altre risposte che vedo sono confuse e alcune cambiano la logica; introdurre bug.
Ian Boyd,

8
@holodoc Una soluzione migliore per esprimere la tua opinione sarebbe quella di creare una risposta che dica che ritieni che l'originale sia il modo migliore ed elaborare il PERCHÉ ritieni che sia così. ciò consente anche ad altre persone di schierarsi facilmente con la tua risposta votandola.
Chuck van der Linden

Risposte:


721

Puoi semplicemente usare:

v = 1 - v;

Questo ovviamente presuppone che la variabile sia inizializzata correttamente, ovvero che abbia solo il valore 0 o 1.

Un altro metodo più breve ma che utilizza un operatore meno comune:

v ^= 1;

Modificare:

Per essere chiari; Non ho mai affrontato questa domanda come code golf, solo per trovare un modo breve di svolgere il compito senza usare trucchi oscuri come gli effetti collaterali degli operatori.


206
Queste sono belle linee di codice, come vetro finemente tagliato o rare orchidee fiorite. Adoro il modo in cui hai raggiunto direttamente il livello logico e hai affrontato direttamente la matematica di 1 e 0 con le operazioni più ottimali possibili. Userò questi nei miei progetti, ma sfortunatamente, quando avrò bisogno che il codice sia compreso dai colleghi, dovrò impostare un approccio più basato sulla logica. Grazie però, la tua risposta ha reso la mia giornata.
Ollie Glass

37
Puoi sempre aggiungere un commento dicendo ciò che fa il codice.
Prusse,

25
@Kevin: non è vero che questo chiaramente non risponde alla domanda come chiesto. Il q ha detto "Voglio alternare una variabile tra 0 e 1." Un'interpretazione molto ragionevole è che ciò implica che il valore della variabile è già 0 o 1. Questa interpretazione / limitazione è stata resa esplicita nella risposta. A cosa al mondo puoi obiettare?
LarsH

50
@Matthew per dire che qualcuno che non trova v ^= 1chiaro dovrebbe smettere di programmare è un po 'duro penso. Come precedentemente affermato, non è uno degli operatori più comuni e non fa la stessa cosa di v = v ^ 1. Inoltre, l'operatore intende qualcosa di completamente diverso in diverse lingue (VB). Sì, una rapida occhiata ti dirà che è un operatore XOR e capirai cosa sta facendo, ma a molti potrebbe non essere ovvio a prima vista. Non penso che ciò significhi che devi lasciare il tuo lavoro.
JD Isaacks,

80
Se salvi 15 caratteri scrivendo questo ma poi usi 40 caratteri di commenti per spiegarlo, è davvero un miglioramento?
Michael Myers

343

Since 0è un falsevalore ed 1è un truevalore.

v = (v ? 0 : 1);

Se sei felice di usare truee al falseposto dei numeri

v = !v;

o se devono essere numeri:

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

55
basta mettere la magia +prima di quello !. Ohhh che sembra davvero sporco! ma fico: p
jAndy il

1
@Quentin - questo romperà il codice del ragazzo se ha switch(v){ case 0 ...o se (v == 0) o se v === 0. Stai cambiando il suo risultato oltre al suo approccio ....
Brian

34
Fare uno smiley di esso: ({v :+! v}).v.
pimvdb,

17
@Brian: non con quel +segno magico ! ¯ \ _ (ツ) _ / ¯
jAndy

11
+1 per v = (v ? 0 : 1)JS chiaro e idiomatico.
Bennett McElwee,

200

v = (v + 1) % 2e se hai bisogno di scorrere più valori basta cambiare 2per (n + 1). Di 'che hai bisogno di un ciclo di 0,1,2 v = (v + 1) % 3.


2
Adoro il ciclo! È davvero intelligente.
Ollie Glass

16
+1 per pensare al toggle come un ciclo. Semplice considerando quanto sia flessibile.
Guffa,

3
+1 per fornire una soluzione modulare che sia anche robusta. In pratica probabilmente vorrai usare una constvariabile al posto dei numeri magici 2, 3, ...
oosterwal

2
Modo più breve (hacker): ++v % 3se vuoi scorrere tra 0, 1, 2
haraldmartin,

75

Puoi scrivere una funzione per essa e usarla come:

v = inv(v)


30
+1 Sono pienamente d'accordo che questa sia la soluzione più pulita (... ma poi cosa succede nella invfunzione: P)
Lea Hayes

4
Vorrei poter dare questa risposta più di un semplice +1. Se il codice comune non è palesemente ovvio, dovrebbe essere racchiuso in una funzione con un nome descrittivo.
TehShrike,

11
@TehShrike consideri invun nome descrittivo?
Bennett McElwee,

3
@Bennett McElwee: inv = invert. Mi è sempre sembrata un'abbreviazione comune.
Daniel

51
Perché abbreviarlo allora, chiamalo 'invert' o 'toggle' e fai in modo che il codice sia leggibile. non è come se stessimo provando ad adattare questa roba su una punchcard da 80 colonne o qualcosa del genere.
Chuck van der Linden,

50

Se non ti interessa alcuna possibilità diversa da 1:

v = v ? 0 : 1;

Nel caso precedente, v finirà per essere 1 se v è 0, falso, indefinito o nullo. Fai attenzione usando questo tipo di approccio - v sarà 0 anche se v è "ciao mondo".


2
Questo non capovolge il valore. Intendi v = v ? 0 : 1.
Guffa,

3
@Guffa - +1 per aver catturato la mia dislessia ...
Brian

3
Questa è la mia risposta basata sulla logica preferita che posso usare con i colleghi (vedo la risposta di @ Guffa come basata sul numero). Mi piace il modo in cui hai eseguito il test non necessario (v == 0) e le parentesi quadre, rimuovendolo fino al conteggio minimo assoluto dei caratteri. Grazie.
Ollie Glass

1
Sono anche un grande fan della risposta di @ Guffa - nelle parole di lynard skynard, mantienilo semplice;)
Brian

2
+1 per comprendere i valori "veritieri".
zzzzBov,

44

Linee come v = 1 - v, o v ^= 1ov= +!v faranno tutte il lavoro fatto, ma costituiscono ciò che definirei hack. Queste non sono belle righe di codice, ma trucchi economici per ottenere l'effetto desiderato.1 - vnon comunica "attiva o disattiva il valore tra 0 e 1". Questo rende il tuo codice meno espressivo e introduce un posto (anche se piccolo) in cui un altro sviluppatore dovrà analizzare il tuo codice.

Avere invece una funzione come v = toggle(v)comunica l'intento al primo sguardo.


8
-1, sul serio, v=1-vnon comunica l'interruttore?
Blindy,

22
1-vpuò davvero comunicare alternativamente, ma questa è l'unica cosa che comunica. Ad esempio, può anche comunicare una linea con zero in v=1oppure una trasformazione di mirroring centrata su v=0.5. In questo senso è relativamente ambiguo. È vero che sapere che vpuò solo essere 0o 1limitare il suo significato previsto, ma che costringe altri sviluppatori (o il tuo sé futuro) a comprendere quel contesto prima di essere in grado di comprendere questa semplice linea. Non puoi essere molto più chiaro div = toggle(v)
Ray

10
v ^= 1è perfettamente chiaro se capisci le operazioni logiche, tuttavia, quale sarebbe meglio se sei un programmatore. Penso che sia la differenza tra questo e v=1-v; una è un'operazione logica e l'altra un'operazione aritmetica, e stiamo provando a rappresentare un concetto logico non matematico.
Matteo Leggi il

6
@Matthew Read: Questa è un'ottima affermazione, che riassume bene i miei pensieri: "stiamo cercando di rappresentare un concetto logico non matematico". Anche v ^= 1ha una certa ambiguità, però, che può essere interpretato come un bit-xor.
Ray

6
per i programmatori (e sì, intendo i geek come noi), questi sono abbastanza chiari. Non sono hack, perché sono soluzioni eleganti per la loro semplicità.
gion_13,

38

(L' onestà e l'integrità matematica - dato il numero di voti su questa "risposta" - mi hanno portato a modificare questa risposta. Ho resistito il più a lungo possibile perché era inteso come una battuta breve e non come qualcosa di "profondo", quindi inserendo qualsiasi spiegazione sembrava contraria allo scopo. Tuttavia, i commenti stanno chiarendo che dovrei essere chiaro per evitare incomprensioni. )

La mia risposta originale:

La formulazione di questa parte della specifica:

Se è 0, voglio impostarlo su 1, altrimenti impostarlo su 0.

implica che la soluzione più accurata è:

v = dirac_delta(0,v)

In primo luogo, la confessione: ho fatto mettere le funzioni delta confusi. Il delta di Kronecker sarebbe stato leggermente più appropriato, ma non tanto quanto volevo qualcosa che fosse indipendente dal dominio (il delta di Kronecker è principalmente usato solo per numeri interi). Ma non avrei dovuto usare le funzioni delta, avrei dovuto dire:

v = characteristic_function({0},v)

Vorrei chiarire. Ricordiamo che una funzione è una tripla, (X, Y, f) , dove X e Y sono insiemi (chiamato il dominio e codominio rispettivamente) ed f è una regola che assegna un elemento di Y per ogni elemento di X . Scriviamo spesso il triplo (X, Y, f) come f: X → Y . Dato un sottoinsieme di X , diciamo A , esiste una funzione caratteristica che è una funzione χ A : X → {0,1} (può anche essere considerata una funzione di un codice più grande come ℕ o ℝ). Questa funzione è definita dalla regola:

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

Se ti piacciono le tabelle di verità, è la tabella di verità per la domanda "L'elemento x di X è un elemento del sottoinsieme A ?".

Quindi da questa definizione, è chiaro che la funzione caratteristica è ciò che è necessario qui, con X un grande set contenente 0 e A = {0} . Questo è quello che avrei dovuto scrivere.

E così per le funzioni delta. Per questo, dobbiamo conoscere l'integrazione. O lo sai già o non lo sai. Se non lo fai, nulla di ciò che posso dire qui ti parlerà delle complessità della teoria, ma posso fare un riassunto di una frase. Una misura su un set X è essenzialmente "ciò che è necessario per far funzionare le medie". Vale a dire che se abbiamo un set X e una misura μ su quell'insieme allora esiste una classe di funzioni X → ℝ , chiamate funzioni misurabili per le quali l'espressione X f dμ ha senso ed è, in un certo senso vago, il "medio" di f su X .

Data una misura su un set, si può definire una "misura" per sottoinsiemi di quel set. Questo viene fatto assegnando a un sottoinsieme l'integrale della sua funzione caratteristica (supponendo che si tratti di una funzione misurabile). Questo può essere infinito o indefinito (i due sono leggermente diversi).

Ci sono molte misure in giro, ma ce ne sono due importanti qui. Uno è la misura standard sulla linea reale, ℝ. Per questa misura, quindi f è praticamente ciò che ti viene insegnato a scuola (il calcolo è ancora insegnato nelle scuole?): Sommare piccoli rettangoli e prendere larghezze sempre più piccole. In questa misura, la misura di un intervallo è la sua larghezza. La misura di un punto è 0.

Un'altra misura importante, che funziona su qualsiasi set, è chiamata misura del punto . È definito in modo che l'integrale di una funzione sia la somma dei suoi valori:

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

Questa misura assegna a ciascun singleton impostare la misura 1. Ciò significa che un sottoinsieme ha una misura finita se e solo se è essa stessa finita. E pochissime funzioni hanno un integrale finito. Se una funzione ha un integrale finito, deve essere diversa da zero solo su un numero numerabile di punti. Quindi la stragrande maggioranza delle funzioni che probabilmente conoscete non hanno un integrale finito in questa misura.

E ora funzioni delta. Prendiamo una definizione molto ampia. Abbiamo uno spazio misurabile (X, μ) (così che è un set con una misura su di esso) e un elemento a ∈ X . Noi "definiamo" la funzione delta (secondo una ) per essere il "funzione" δ un : X → ℝ con la proprietà che δ una (x) = 0 se x ≠ una e X δ un df = 1 .

Il fatto più importante su questo per ottenere una presa in considerazione è questo: la funzione delta non deve necessariamente essere una funzione . E ' non è correttamente definito: Non ho detto quello che Æ un (a) è.

Quello che fai a questo punto dipende da chi sei. Il mondo qui si divide in due categorie. Se sei un matematico, dici quanto segue:

Ok, quindi la funzione delta potrebbe non essere definita. Diamo un'occhiata alle sue proprietà ipotetiche e vediamo se riusciamo a trovare una casa adeguata dove è definita. Possiamo farlo e finiamo con le distribuzioni . Queste non sono (necessariamente) funzioni, ma sono cose che si comportano un po 'come funzioni, e spesso possiamo lavorare con loro come se fossero funzioni; ma ci sono alcune cose che non hanno (come "valori"), quindi dobbiamo stare attenti.

Se non sei un matematico, dici quanto segue:

Ok, quindi la funzione delta potrebbe non essere definita correttamente. Chi lo dice? Un gruppo di matematici? Ignorali! Cosa sanno?

Avendo offeso il mio pubblico, continuerò.

Il delta dirac è generalmente considerato la funzione delta di un punto (spesso 0) nella linea reale con la sua misura standard. Quindi coloro che si lamentano nei commenti su di me che non conoscono i miei delta lo fanno perché usano questa definizione. Mi scuso con loro: anche se posso evitarlo usando la difesa del matematico (come reso popolare da Humpty Dumpty : ridefinire semplicemente tutto in modo che sia corretto), è una cattiva forma usare un termine standard per significare qualcosa di diverso.

Ma v'è una funzione delta che fa fare quello che voglio fare ed è quello che ho bisogno di te qui. Se prendo un provvedimento punto su una serie X poi c'è è una vera e propria funzione di δ una : X → ℝ che soddisfa i criteri di una funzione delta. Questo perché stiamo cercando una funzione X → ℝ che è zero tranne che in a e tale che la somma di tutti i suoi valori sia 1. Tale funzione è semplice: l'unica informazione mancante è il suo valore in a , e per fare in modo che la somma sia 1, assegniamo semplicemente il valore 1. Questo non è altro che la funzione caratteristica su {a} . Poi:

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

Quindi, in questo caso, per un set singleton, la funzione caratteristica e la funzione delta concordano.

In conclusione, ci sono tre famiglie di "funzioni" qui:

  1. Le funzioni caratteristiche degli insiemi singleton,
  2. Le funzioni delta,
  3. Le funzioni delta di Kronecker.

Il secondo è il più generale in quanto uno qualsiasi degli altri ne è un esempio quando si utilizza la misura del punto. Ma il primo e il terzo hanno il vantaggio di essere sempre funzioni autentiche. Il terzo è in realtà un caso speciale del primo, per una particolare famiglia di domini (numeri interi o alcuni sottoinsiemi).

Così, finalmente, quando ho originariamente scritto la risposta che non stavo pensando correttamente (non vorrei andare fino al punto di dire che ero confuso , come spero che ho appena dimostrato che non so di cosa sto parlando quando In realtà penso prima, non ci ho pensato molto). Il significato abituale del delta di dirac non è ciò che si desidera qui, ma uno dei punti della mia risposta è che il dominio di input non è stato definito, quindi anche il delta di Kronecker non avrebbe avuto ragione. Quindi la migliore risposta matematica (a cui stavo mirando) sarebbe stata la funzione caratteristica .

Spero che sia tutto chiaro; e spero anche di non dover mai più scrivere un pezzo matematico usando entità HTML al posto delle macro TeX!


37
+1 - Se potessi sottovalutare Quentin per non conoscere la funzione dirac_delta lo farei. Mi piacerebbe sapere in quale college è andato perché non credo che assumerei qualcuno da lì se non sapessero nemmeno qualcosa di così fondamentale per l'elaborazione digitale. Vorrei inoltre sottovalutare Quentin per la sua incapacità di cogliere il pizzico di umorismo che stavi tentando.
Dunk

23
Se declassassi ogni risposta che non capivo ... avrei declassato molte risposte.
Seamus,

4
Ciao Andrew, è passato un po 'di tempo.
Tim Down,

4
@Tim: buon dolore, così ha fatto! E come sta il vescovo delle Bermuda? (Me lo sono ricordato giusto?) Immagino che questo commento non sia il posto migliore per raggiungerlo, anche se ... 17 anni, vero?
Andrew Stacey,

3
@ Cԃ ա ԃ "Questa risposta non è riuscita ..." sospiro . Hai letto che sono un matematico, vero? Questa risposta funziona perfettamente per un programmatore sferico nel vuoto, quindi non so di cosa ti lamenti.
Andrew Stacey,

35

Si potrebbe fare

v = Math.abs(--v);

Il decremento imposta il valore su 0 o -1, quindi Math.absconverte -1 in +1.


27
Ciò si è trasformato in una competizione "Genera 10000 modi per svolgere un compito semplice". E mi piacciono tutti i modi ahah.
Gios

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

15
@Benoit: la tua formula è uguale a 1 sia per v = 0 che v = 1. QUESTO è corretto però! v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));: D
Teo.sk,

2
Ciò non cambierebbe mai il valore. Se v = 1allora v = Math.Abs(-1)che è +1. Se v = 0allora v = Math.Abs(-0)che è 0.
Paul

1
+1 E questo era l'altro mio ... Grr.
ricorsivo

34

in generale ogni volta che è necessario alternare tra due valori, è possibile sottrarre il valore corrente dalla somma dei due valori di attivazione / disattivazione:

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

2
Questo è interessante e creativo ma potenzialmente pericoloso. Se vviene danneggiato, inizierà improvvisamente a passare tra due diversi valori. (Solo qualcosa da considerare ...)
oosterwal,

1
+1 per l'idea interessante. non che l'OP o chiunque altro lo userà davvero in queste circostanze, ma questa informazione dovrebbe esistere da qualche parte nel cervello per sempre.
Shimmy Weitzhandler,

3
@oosterwal: Quindi sicuramente il problema sta nella corruzione ...
GManNickG

@GManNickG: prima o poi si verificherà un danneggiamento dei dati, quindi dobbiamo essere consapevoli delle conseguenze della mancata rilevazione. Se vviene normalmente utilizzato per eseguire alternativamente due stati da un elenco di tre o più stati, una corruzione vpotrebbe far sì che il programma esegua alternativamente due stati completamente diversi, con conseguenti risultati imprevisti e indesiderati. La lezione da togliere a questo è: eseguire sempre controlli di plausibilità sui dati.
oosterwal,

33

Se deve essere un numero intero 1 o 0, il modo in cui lo stai facendo va bene, anche se non sono necessarie parentesi. Se questi a devono essere usati come booleani, allora puoi semplicemente fare:

v = !v;

10
questo non determinerà che la "v" di Ollie sia impostata su un risultato booleano, non su un numero intero?
Brian

12
Sì lo farà, e l'ho avvertito nella frase sopra la riga di codice. Se questi a devono essere usati come booleani
Michael Berkowski il

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

È abbastanza !


7
Più un'opinione che una risposta, non credi?
Brian

16
@Brian: "meglio" in realtà è tutto basato sull'opinione.
pimvdb,

3
Mi piace come hai rimosso le parentesi quadre - che taglia un paio di personaggi!
Ollie Glass

9
@Brian: la " risposta " è "No, non esiste un modo migliore di scrivere v = (v==0 ? 1 : 0);" . Tutti gli altri stanno trovando modi diversi di giocare a golf; e in realtà non risponde alla domanda. Ecco perché ho votato a favore di questa risposta.
Ian Boyd,

19

Elenco di soluzioni

Ci sono tre soluzioni che vorrei proporre. Tutti loro convertire qualsiasi valore 0(se 1, trueetc.) o 1(se 0, false, nulletc.):

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

e un ulteriore, già menzionato, ma intelligente e veloce (anche se funziona solo per 0s e 1s):

  • v = 1-v

Soluzione 1

È possibile utilizzare la seguente soluzione:

v = 1*!v

Questo prima convertirà il numero intero nel valore booleano opposto ( 0in Truee qualsiasi altro valore in False), quindi lo tratterà come numero intero durante la moltiplicazione per 1. Di conseguenza 0verrà convertito in 1e qualsiasi altro valore in 0.

Come prova vedi questo jsfiddle e fornisci tutti i valori che desideri testare: jsfiddle.net/rH3g5/

I risultati sono i seguenti:

  • -123convertirà in intero 0,
  • -10convertirà in intero 0,
  • -1convertirà in intero 0,
  • 0convertirà in intero 1,
  • 1convertirà in intero 0,
  • 2convertirà in intero 0,
  • 60convertirà in intero 0,

Soluzione 2

Come notato da mblase75, jAndy aveva un'altra soluzione che funziona come la mia:

v = +!v

Inoltre, dapprima rende booleano dal valore originale, ma utilizza +invece di1* convertirlo in numero intero. Il risultato è esattamente lo stesso, ma la notazione è più breve.

Soluzione 3

Un altro approccio è utilizzare l' ~~operatore:

v = ~~!v

È abbastanza raro e converte sempre in numero intero da booleano.


In JavaScript, puoi aggiungere un prefisso a una variabile +per convertirla in un numero, quindi +!vequivale alla tua soluzione (la soluzione di jAndy nei commenti dell'OP).
Blazemonger,

@ mblase75: Sì, hai ragione, 1*può essere sostituito da +quando cerchi di convertire il valore booleano in numero intero. Tutto il resto nella mia risposta rimane lo stesso. La risposta di jAndy è corretta, ma la mia è più dettagliata. Aggiungerò la sua soluzione alla mia risposta.
Tadeck,

@Tadeck +1 per la bella idea.
Shimmy Weitzhandler,

17

Per riassumere un'altra risposta, un commento e la mia opinione, suggerisco di combinare due cose:

  1. Utilizzare una funzione per attivare / disattivare
  2. All'interno di questa funzione usa un'implementazione più leggibile

Ecco la funzione che potresti inserire in una libreria o magari racchiuderla in un plugin per un altro framework Javascript.

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

E l'uso è semplicemente:

v = inv(v);

I vantaggi sono:

  1. Nessuna duplicazione di codice
  2. Se tu o qualcuno lo rileggerete in futuro, capirete il codice in un minimo di tempo.

Sono loro? Ho eseguito un test rapido: jsperf.com/function-vs-no-function/2 e sembra che la differenza non sia molto.
Martin Schlagnitweit,

25
7.5ns contro 8.8ns. Quel 1.3 nanosecondi extra ti ucciderà davvero.
Ian Boyd,

5
Con tutto il tempo che ho risparmiato, ho portato la mia famiglia a Disney World! :-)
Tom

1
Totalmente corretto. Le persone che scrivono soluzioni "intelligenti" probabilmente non hanno mai dovuto mantenere gli altri programmatori "gemme"
Avi

1
perchè no function toggle(i){ return i == 0 ? 1 : 0 }?
Billy Moon,

13

Non so perché vuoi creare i tuoi booleani? Mi piacciono le sintassi funky, ma perché non scrivere un codice comprensibile?

Questo non è il più breve / veloce, ma il più chiaro (e leggibile per tutti) sta usando il ben noto stato if / else:

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

Se vuoi essere veramente chiaro, dovresti usare i booleani invece dei numeri per questo. Sono abbastanza veloci per la maggior parte dei casi. Con i booleani, potresti semplicemente usare questa sintassi, che vincerà in breve:

v = !v;

1
Questa sarebbe in realtà la mia risposta preferita; ma l' operatore ternario contro if-else è una guerra santa su cui non volevo accendere la miccia. Detto questo, penso che la prima riga dovrebbe essere === 0. Con l'input di esempio di 7, l'output corretto è 0, ma verrà emesso 1.
Ian Boyd,

4
È utile correggere silenziosamente un input come 7 anziché generare un'eccezione di qualche tipo? Voglio dire, se qualche altro bit di codice avesse le mani sul 7 quando si aspettava solo 0 o 1, prima che il codice correggesse il valore?
Chuck van der Linden,

12

Un'altra forma della tua soluzione originale:

v = Number(v == 0);

EDIT: Grazie a TehShrike e Guffa per aver segnalato l'errore nella mia soluzione originale.


4
L'operatore == restituisce un valore booleano (anziché un numero intero) in molti sistemi. Funzionerebbe solo se v fosse definito come un numero intero e la lingua fosse interessante con il cast automatico da booleano a intero.
TehShrike,

Verissimo. Stavo rispondendo alla domanda nel contesto di JavaScript (come è stata taggata la domanda).
Kurt Kaylor,

@Kurt Kaylor: Javascript è uno dei sistemi in cui l'operatore == restituisce un valore booleano, quindi non fa lo stesso della soluzione originale.
Guffa,

@Guffa: sto sfruttando il fatto che javascript è un linguaggio debolmente tipizzato con conversione di tipo implicita (es. '0.0000' == 0, 0 == "", false == "", false == 0, 1 == vero, ecc.). Posso usare il valore booleano restituito nello stesso modo in cui posso usare un numero intero di valore 0 o 1. Prova, ad esempio, a valutare "2 + true" in una console JavaScript, otterrai 3.
Kurt Kaylor

1
@Kurt Kaylor: funziona solo in situazioni in cui si forza una conversione implicita. Prova ad esempio 'opacity:'+truee finisci con opacity:trueinvece di opacity:1.
Guffa,

11

Lo renderei più esplicito.

Cosa vsignifica?

Ad esempio, quando v è un certo stato. Crea uno stato dell'oggetto. In DDD un oggetto valore.

Implementare la logica in questo oggetto valore. Quindi puoi scrivere il tuo codice in un modo più funzionale che è più leggibile. La commutazione dello stato può essere effettuata creando un nuovo stato basato sullo stato corrente. L'istruzione / logica if viene quindi incapsulata nel tuo oggetto, che puoi annullare. Un valoreOggetto è sempre immutabile, quindi non ha identità. Quindi per modificarne il valore devi crearne uno nuovo.

Esempio:

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
oltre l'ingegneria?
Alejandro 5042

6
+1 per farmi ridere
Denshi il


10

Questo manca:

v = [1, 0][v];

Funziona anche come round robin:

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 ...

O

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

Il fascino dell'ultima soluzione, funziona anche con tutti gli altri valori.

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

Per un caso molto speciale, come ottenere un valore (che cambia) e undefined, questo modello può essere utile:

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

9

Dato che si tratta di JavaScript, possiamo usare l'unario +per convertire in int:

v = +!v;

Ciò renderà logico NOTil valore di v(dare trueif v == 0o falseif v == 1). Quindi convertiamo il valore booleano restituito nella sua rappresentazione intera corrispondente.



7

Ancora uno: v=++v%2

(in C sarebbe semplice ++v%=2)

ps. Sì, lo so che è una doppia assegnazione, ma questa è solo una riscrittura grezza del metodo C (che non funziona così com'è, perché l'operatore di pre-incremento JS non dovrebbe restituire il valore.


3
La tua versione C è illegale; non puoi modificare il risultato di un ++operatore (non è un valore). Per quanto riguarda v=++v%2, stai modificando vdue volte. Non so se sia ben definito in JavaScript, ma non è necessario. v = (v+1) % 2.
Keith Thompson,

Almeno in c++esso lo è, poiché l'operatore di pre-incremento ha una priorità più elevata e modifica la variabile "sul posto", in modo che possa essere utilizzata come lvalue. Penso che l'implementazione di JS ++sia tale che non può essere trattato come un valore: / E sì, questo è ridondante, ma stavo cercando di mostrare solo un altro metodo - ci sono già soluzioni migliori pubblicate :)
Adam Jurczyk

3
+1. Può essere scritto come v = (v + 1)% 2.
niktrs,

7

Se hai la certezza che il tuo input sia 1 o 0, puoi usare:

v = 2+~v;

7

definire un array {1,0}, impostare v su v [v], quindi v con un valore di 0 diventa 1 e vica versa.


La mia soluzione è corretta, se non ti piace, scrivi perché. Il tuo commento non aiuta nessuno. La mia soluzione legge una variabile, anziché prendere una decisione. Ciò richiede meno CPU.
S ..

5

Un altro modo creativo di farlo, con l' vessere uguale a qualsiasi valore, tornerà sempre 0o1

v = !!v^1;

3
due non !!portano a nulla in matematica logica, si può mettere !!!!lì e saranno gli stessi ma risultanti 4 operazioni non necessarie
Alex K

10
@Alex: !!lancerà un bool. !!(1) === truee!!(0) === false
nickf

1
@nickf: aha, quindi credo che v = Boolean(v^1)sarebbe più informativo, grazie per aver spiegato - non ho pensato al casting
Alex K

1
@Alex, "matematica logica"? Ecco perché i matematici sono programmatori poveri. Non fraintendetemi; i bravi programmatori sono anche bravi a capire la matematica. Ma questo non ha nulla a che fare con la matematica logica. È un costrutto linguistico che, data qualsiasi espressione, almeno in Javascript, !lo trasformerà in booleano. L'aggiunta di un altro !annulla quel valore booleano. Il casting è implicito qui e il risultato finale funziona. Non è necessario per -1.
Yanick Rochon,

1
non sono affatto un matematico. puoi provare questo e vederti jsperf.com/javascript-boolean-test
Alex K

4

Se i valori possibili per v sono solo 0 e 1, quindi per qualsiasi numero intero x, l'espressione: v = Math.pow ((Math.pow (x, v) - x), v); attiva / disattiva il valore.

So che questa è una brutta soluzione e l'OP non lo stava cercando ... ma stavo pensando a un'altra soluzione quando ero nel gabinetto: P




1

Se ci sono solo due valori, come in questo caso (0, 1), credo che sia inutile usare int. Piuttosto vai per il booleano e lavora a pezzi. So che sto assumendo, ma in caso di alternanza tra due stati booleani sembra essere la scelta ideale.


1

Bene, come sappiamo che solo in javascript quel confronto booleano ti darà anche il risultato atteso.

cioè v = v == 0è abbastanza per quello.

Di seguito è riportato il codice per questo:

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/

Spero che questo ti possa aiutare :)


Funziona per alternare un valore, ma il valore non alterna tra 0 e 1, ma piuttosto tra truee false. È possibile utilizzare v == 0per determinare il valore della variabile in una condizione, ma se si desidera utilizzare il valore 0 o 1, è necessario utilizzare qualcosa di simile v == 0 ? 0 : 1o Number(v)per ottenerlo. (Inoltre, puoi usare v = !v;per alternare tra truee false.)
Guffa,

sì capito .. grazie :)
Vikash Pandey,

0

v = Numero (! v)

Digiterà cast il valore booleano invertito su Number, che è l'output desiderato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.