Postoji li bolji način za pisanje v = (v == 0? 1: 0);

Želim prebaciti varijablu između 0 i 1. Ako je 0, želim ga postaviti na 1, inače, ako je 1, želim ga postaviti na 0.

To je tako temeljna operacija koju toliko često pišem da bih htjela istražiti najkraći i maksimalni mogući način da to učinim. Ovo je moje najbolje do sada:

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

Možete li ovo poboljšati?

Edit: pitanje je kako napisati gore navedenog operatora u najmanji znakova, a da pritom zadrži jasnoću - kako je to "nije pravo pitanje"? Nije bio namijenjen vježbama s golf igralištem s kodom, iako su neki ljudi došli do nekih zanimljivih odgovora, poput golfa. Lijepo je vidjeti da se golf koristi konstruktivno i promišljeno.

428
02 авг. Ollie Stakleni set 02 aug. 2011-08-02 14:22 '11 u 14:22 2011-08-02 14:22
@ 30 odgovora

Možete jednostavno koristiti:

 v = 1 - v; 

To, naravno, pretpostavlja da je varijabla ispravno inicijalizirana, tj. Da ima samo vrijednost 0 ili 1.

Druga metoda koja je kraća, ali koristi manje općeg operatora:

 v ^= 1; 

Uredi:

Budite jasni; Nikad se nisam bavio tim problemom kao kôd za golf, samo da bih pronašao kratak način za izvršenje zadatka bez korištenja skrivenih trikova, kao što su nuspojave operatora.

654
02 авг. odgovor je dat Guffa 02 aug. 2011-08-02 14:33 '11 u 14:33 2011-08-02 14:33

Budući da je 0 false , 1 je true .

 v = (v ? 0 : 1); 

Ako ste sretni da koristite true i false umjesto brojeva

border=0
 v = !v; 

ili ako moraju biti brojevi:

 v = +!v;  
330
02 авг. odgovor je dan Quentin 02 aug. 2011-08-02 14:26 '11 u 14:26 2011-08-02 14:26

v = (v + 1) % 2 , i ako trebate ponavljati više vrijednosti, jednostavno promijenite 2 u (n + 1) . Recimo da trebate okrenuti 0,1,2, samo napraviti v = (v + 1) % 3 .

197
02 авг. odgovor je dat Prusse 02 aug. 2011-08-02 14:37 '11 u 14:37 2011-08-02 14:37

Možete napisati funkciju za nju i koristiti je kao:

v = inv(v)

75
02 авг. Odgovor je dan Daniel 02 aug. 2011-08-02 14:25 '11 u 14:25 2011-08-02 14:25

Ako ne trebate drugu mogućnost osim 1:

 v = v ? 0 : 1; 

U gore navedenom slučaju, v će završiti kao 1 ako je v jednako 0, false, undefined ili null. Budite oprezni, koristeći ovaj pristup - v će biti jednako 0, čak i ako je v “hello world”.

50
02 авг. odgovor je dat Brian 02 aug. 2011-08-02 14:26 '11 u 14:26 2011-08-02 14:26

Linije tipa v = 1 - v , ili v ^= 1 ili v= +!v će raditi ovaj posao, ali čine ono što bih ja nazvao hack. To nisu lijepe linije koda, nego jeftini trikovi koji imaju željeni učinak. 1 - v ne veže "prebacivanje između 0 i 1". To čini vaš kod manje izražajnim i uvodi mjesto (iako malo) gdje će drugi programer morati analizirati vaš kôd.

Umjesto toga, funkcija poput v = toggle(v) odmah prenosi namjeru.

43
02 авг. odgovor je dao Ray 02 aug. 2011-08-02 17:17 '11 u 17:17 2011-08-02 17:17

(Poštenje i matematički integritet - s obzirom na broj glasova o tom "odgovoru" - natjerao me je da uredim ovaj odgovor. Držao sam se što je duže moguće, jer je bio zamišljen kao kratka fraza, a ne kao nešto "duboko", pa se čini da je bilo kakvo objašnjenje Međutim, komentari jasno pokazuju da moram biti jasan kako bi se izbjegli nesporazumi.)

Moj je izvorni odgovor:

Tekst ovog dijela specifikacije je:

Ako je 0, želim ga postaviti na 1, inače ga postaviti na 0.

znači najpreciznije rješenje:

 v = dirac_delta(0,v) 

Prvo, ispovijed: učinio sam svoje delta funkcije zbunjenim. Kroneckerova delta bi bila malo prikladnija, ali ne onoliko koliko sam htjela, ono što je bilo neovisno o domeni (Kronecker delta se uglavnom koristila samo za cijele brojeve). Ali stvarno nisam uopće trebao koristiti delta funkcije, trebao sam reći:

 v = characteristic_function({0},v) 

Dopustite mi da pojasnim. Podsjetimo se da je funkcija trostruka (X, Y, f), gdje su X i Y skupovi (označeni kao regija i codman), a f je pravilo koje svakom elementu X dodjeljuje element Y. Često napišemo trostruki (X, Y). f) kao f: X i desna strelica; Y. Za podskup od X, recimo A, postoji karakteristična funkcija, koja je funkcija funkcije chi; O : X i desna strelica; {0,1} (također se može promatrati kao funkcija većeg kodena, kao što je nopf; ili Ropf;). Ova funkcija određena je pravilom:

chi; A (x) = 1 ako je x in; A i chi; A (x) = 0 ako je x notin; A.

Ako vam se sviđaju tablice istine, ovo je tablica istine za pitanje "Je li element x od X element podskupa A?".

Dakle, iz ove definicije jasno je da je karakteristična funkcija ono što je ovdje potrebno, a X je neki veliki skup koji sadrži 0 i A = {0}. To je ono što sam trebao napisati.

Dakle, za delta funkcije. Za to trebamo znati o integraciji. Ili to već znate ili ne. Ako to ne učinite, ovdje ne mogu ništa reći, reći ću vam o suptilnostima teorije, ali mogu dati sažetak prijedloga. Mjera na X-u u biti je "ono što je potrebno za prosjek prosjeka." To jest, ako imamo skup X i mjeru? na tom skupu postoji klasa funkcija X rightarrow; Ropf; nazivamo mjerljive funkcije, za koje je izraz int; X fd > ima smisla iu nekom neodređenom smislu ima "prosječnu" vrijednost f iznad X.

S obzirom na mjeru na skupu, možete definirati "mjeru" za podskupove ovog skupa. To se postiže dodjeljivanjem integrala podskupini njegove karakteristične funkcije (uz pretpostavku da je to mjerljiva funkcija). Može biti beskonačna ili nedefinirana (dva su malo drugačija).

Postoje mnoge mjere, ali ovdje su dvije važne. Jedan od njih je standardna mjera na pravoj liniji, Ropf;. Za ovu mjeru, zatim int; Ropf; fd mu; to je ono što vas uče u školi (da li račun još poučava u školama?): sažeti male pravokutnike i uzeti manju i manju širinu. U ovoj mjeri mjera intervala je njegova širina. Točka mjera je 0.

Još jedna važna mjera koja djeluje na bilo koji skup naziva se mjerilo točke. Definirana je tako da je integral funkcije zbroj njegovih vrijednosti:

int; X fd > = sum; x in; X f (x)

Ova mjera dodjeljuje svakom pojedinačnom skupu mjeru 1. To znači da podskupina ima konačnu mjeru ako i samo ako je samo-konačna. I vrlo malo funkcija ima konačni integral. Ako funkcija ima konačni integral, ona mora biti različita od nule samo na brojljivom broju točaka. Dakle, velika većina funkcija koje vjerojatno znate nemaju konačni integral za ovu mjeru.

A sada na delta funkcije. Pogledajmo vrlo široku definiciju. Imamo mjerljivi prostor (X, (tako da skup ima mjeru na njemu) i element a in; X. Definiramo delta funkciju (ovisno o a) kao "funkciju" a : X i desnu strelicu; Ropf; s svojstvom da je a (x) = 0 ako je x ne ne; a i int; X ? d mu; = 1.

Najvažnija činjenica o tome kako dobiti a-hold je sljedeća: funkcija delta ne bi trebala biti funkcija . Nije točno definirano: nisam to rekao delta; a (a).

Ono što radite u ovom trenutku ovisi o tome tko ste. Ovdje je svijet podijeljen u dvije kategorije. Ako ste matematičar, kažete sljedeće:

Dobro, tako da se delta funkcija ne može odrediti. Pogledajmo njegova hipotetička svojstva i vidimo postoji li tamo prikladna kuća gdje će biti određena. Možemo to i dobiti raspodjelu. To nisu (nužno) funkcije, već stvari koje se ponašaju kao funkcije i često s njima možemo raditi kao da su funkcije; ali postoje određene stvari koje oni nemaju (na primjer, "značenja"), pa moramo biti oprezni.

Ako niste matematičar, kažete sljedeće:

U redu, funkcija delta može biti pogrešno definirana. Tko to kaže? Gomila matematičara? Zanemarite ih! Što oni znaju?

Nakon što sam uvrijedio moju publiku, nastavit ću.

dirac delta strong> se obično smatra delta funkcijom točke (često 0) u pravoj liniji sa svojom standardnom mjerom. Stoga, oni koji se žale na komentare na mene, ne znajući moje delte, to čine zato što koriste tu definiciju. Za njih se ispričavam: iako se za to mogu ispričati, koristeći zaštitu matematike (kao što je popularan Humpty Dumpty: samo redefinirajte sve tako da je to točno), loš oblik je koristiti standardni izraz za nešto drugo.

Ali postoji delta funkcija koja radi ono što želim, i to je ono što mi treba ovdje. Ako uzmem mjeru točke na skupu X, tada postoji prava funkcija delta; a : X i desna strelica; Ropf; koji zadovoljava kriterije delta funkcije. To je zato što tražimo funkciju X i desnu strelicu; Ropf; koja je nula, osim a, itd., da je zbroj svih njenih vrijednosti 1. Ova funkcija je jednostavna: jedini nedostaje dio informacije je njegova vrijednost u točki a, a da bi se dobila suma jednaka 1, jednostavno joj dodijelimo vrijednost 1. ništa drugo osim karakteristične funkcije na {a}. zatim:

int; X ? d mu; = sum; x in; X ? a (x) =? a (a) = 1.

Dakle, u ovom slučaju, za singleton skup, karakteristična funkcija i delta funkcija se slažu.

U zaključku, postoje tri obitelji "funkcija":

  • Karakteristične funkcije skupova od jedne točke,
  • Delta funkcije,
  • Kronecker-ove delta funkcije.

Drugi je najčešći, jer je bilo koji drugi primjer za to kada se koristi mjerna točka. Ali prva i treća imaju prednost što su uvijek istinske osobine. Treći je zapravo poseban slučaj prvog, za određenu obitelj domena (cijeli brojevi ili neki njihovi podskupovi).

I konačno, kad sam izvorno napisao odgovor, nisam ispravno razmišljao (ne bih rekao da sam bio zbunjen, jer, nadam se, upravo sam pokazao da znam o čemu govorim kad stvarno Mislim da u početku nisam baš mislila). Uobičajeno značenje delta diraca nije ono što se ovdje traži, ali jedna od točaka mog odgovora je bila da ulazna domena nije definirana, stoga Kronecker-ova delta također ne bi bila točna. Dakle, najbolji matematički odgovor (kojem sam težio) bio bi karakterističan .

Nadam se da je sve to jasno; i nadam se da više neću morati pisati matematički fragment pomoću HTML objekata umjesto TeX makronaredbi!

39
03 авг. odgovor je dan Loop Space 03 aug. 2011-08-03 11:01 '11 u 11:01 2011-08-03 11:01

Mogao bi

 v = Math.abs(--v); 

Smanjenje postavlja vrijednost na 0 ili -1, a zatim Math.abs pretvara -1 u +1.

35
02 авг. odgovor je dao Paul 02 aug. 2011-08-02 15:31 '11 u 15:31 2011-08-02 15:31

Općenito, kada trebate prebacivati ​​između dvije vrijednosti, možete jednostavno oduzeti trenutnu vrijednost od zbroja dvije vrijednosti prebacivanja:

  0,1 -> v = 1 - v 1,2 -> v = 3 - v 4,5 -> v = 9 - v 
34
03 авг. odgovor od Mouna Cheikhna 03 kol 2011-08-03 16:37 '11 u 16:37 2011-08-03 16:37

Ako bi trebao biti cijeli broj od 1 ili 0, onda kako je to u redu, iako nema zagrada je potrebno. Ako se ovi koriste kao logičke vrijednosti, možete jednostavno:

 v = !v; 
34
02 авг. Odgovor dao Michael Berkowski 02. kolovoza. 2011-08-02 14:25 '11 u 14:25 2011-08-02 14:25
 v = v == 0 ? 1 : 0; 

Dosta!

24
02 авг. odgovor je dat nidhin 02 aug. 2011-08-02 14:25 '11 u 14:25 2011-08-02 14:25

Sumirajući još jedan odgovor, komentar i svoje mišljenje, predlažem da kombiniram dvije stvari:

  • Koristite funkciju za prebacivanje
  • Unutar ove funkcije koristite čitljiviju implementaciju.

Ovdje je funkcija koju možete staviti u knjižnicu ili je možda zamotati u dodatak za drugi Javascript okvir.

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

A uporaba je jednostavna:

 v = inv(v); 

prednosti:

  • Nema dupliciranja koda
  • Ako vi ili netko drugi to pročitate u budućnosti, shvatit ćete svoj kod u minimalnom vremenu.
17
02 авг. odgovor dao Martin Schlagnitweit 02 Aug. 2011-08-02 22:00 '11 u 22:00 2011-08-02 22:00

Popis rješenja

Postoje tri rješenja koja bih predložio. Svi oni pretvaraju bilo koju vrijednost u 0 (ako je 1 , true , itd.) Ili 1 (ako je 0 , false , null itd.):

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

i još jedno, već spomenuto, ali pametno i brzo (iako radi samo za 0 i 1 s):

  • v = 1-v

Rješenje 1

Možete koristiti sljedeće rješenje:

 v = 1*!v 

Ovo prvo pretvara cijeli broj u suprotni boolean (od 0 u true i bilo koju drugu vrijednost u false ), a zatim će ga obraditi kao cijeli broj pomnoženo s 1 . Kao rezultat, 0 će se pretvoriti u 1 i svaka druga vrijednost biti će 0 .

Kao dokaz pogledajte ovu jsfiddle i navedite sve vrijednosti koje želite provjeriti: jsfiddle.net/rH3g5/

Rezultati su sljedeći:

  • -123 pretvara se u cijeli broj 0 ,
  • -10 pretvara se u cijeli broj 0 ,
  • -1 pretvara u cijeli broj 0 ,
  • 0 pretvara u cijeli broj 1 ,
  • 1 pretvara u cijeli broj 0 ,
  • 2 pretvara u cijeli broj 0 ,
  • 60 pretvara u cijeli broj 0 ,

Rješenje 2

Kao što je navedeno u mblase75, jAndy je imao drugo rješenje koje radi poput moga:

 v = +!v 

Također prvo stvara boolean vrijednost iz izvorne vrijednosti, ali umjesto 1* koristi + da je pretvori u cijeli broj. Rezultat je potpuno isti, ali oznaka je kraća.

Rješenje 3

Drugi pristup je upotreba ~~ operatora:

 v = ~~!v 

To je prilično neobično i uvijek se pretvara u cijeli broj iz boolean.

17
17 авг. Odgovor je dat Tadeck 17 aug. 2011-08-17 19:45 '11 u 19:45 2011-08-17 19:45

Ne znam zašto želite stvoriti vlastitu logiku? Volim funk sintakse, ali zašto ne napisati jasan kod?

To nije najkraći / najbrži, ali najčišći (i čitljiv za sve) koristi dobro poznato stanje if / else:

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

Ako želite biti zaista jasni, za to biste trebali koristiti logičke vrijednosti umjesto brojeva. Dovoljno su brzi za većinu slučajeva. Pomoću boolea možete jednostavno koristiti ovu sintaksu koja pobjeđuje u kratkom obliku:

 v = !v; 
13
02 авг. odgovor dao Mark Knol 02 Aug. 2011-08-02 22:04 '11 u 22:04 2011-08-02 22:04

Drugi oblik izvornog rješenja:

 v = Number(v == 0); 

EDIT: Zahvaljujući TehShrike i Guffa za ukazivanje na pogrešku u mojoj izvornoj odluci.

12
02 авг. odgovor Kurt Kaylor 02 2011-08-02 19:52 '11 u 19:52 2011-08-02 19:52

Ja bih to učinio eksplicitnijim.

Što znači v ?

Na primjer, kada je v stanje. Stvaranje statusa objekta. U DDD, objekt vrijednosti.

Provedite logiku u ovom objektu vrijednosti. Tada svoj kod možete napisati na funkcionalniji način koji je čitljiviji. Stanje prebacivanja može se izvesti stvaranjem novog stanja na temelju trenutnog stanja. Tada je vaš if-operator / logic enkapsuliran u vaš objekt, koji možete izbrisati. Objekt valueObject je uvijek nepromijenjen, tako da nema identifikatora. Stoga, da biste promijenili vrijednost, morate stvoriti novu.

primjer:

 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); 
11
05 авг. odgovor Marco Franssen 05. kolovoza 2011-08-05 13:33 '11 u 13:33 2011-08-05 13:33

Drugi način za to je:

 v = ~(v|-v) >>> 31; 
10
18 авг. odgovor je dan Eng.Fouad 18 aug. 2011-08-18 22:51 '11 u 10:51 sati 2011-08-18 22:51

Samo za udarce: v = Math.pow(v-1,v) također se prebacuje između 1 i 0.

8
18 авг. Blazemonger je odgovorio 18. kolovoza 2011-08-18 23:13 '11 u 23:13 2011-08-18 23:13

Ovo nedostaje:

 v = [1, 0][v]; 

Isto tako funkcionira kao robinska runda:

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

ili

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

Ljepota posljednjeg rješenja, također radi sa svim ostalim vrijednostima.

 v = {777: 'seven', 'seven': 777}[v]; 
8
24 июня '15 в 16:52 2015-06-24 16:52 odgovor daje Nina Scholz 24. lipnja 2009. u 16:52 sati 2015-06-24 16:52

Još jedna stvar: v=++v%2

(u C to bi bilo samo ++v%=2 )

ps. Da, znam da je to dvostruka svrha, ali ovo je samo neobrađena prerada metode C (koja ne radi onako kako jest, prisiljava JS pre-inkrement operatora dosen't return lvalue).

7
02 авг. odgovor je dao Adam Jurczyk 02 aug. 2011-08-02 21:41 '11 u 21:41 2011-08-02 21:41

Ako ste zajamčeni da je vaš unos 1 ili 0, možete koristiti:

 v = 2+~v; 
7
05 авг. odgovor je dan brandx 05 aug. 2011-08-05 11:15 '11 u 11:15 2011-08-05 11:15

definirajte niz {1,0}, postavite v v [v], tako da v s vrijednošću 0 postaje jednak 1, i vica versa.

7
17 июля '12 в 18:50 2012-07-17 18:50 odgovor je dat Samu 17. srpnja 2012. u 18:50 2012-07-17 18:50

Budući da je ovo JavaScript, možemo koristiti unary + za pretvorbu u int:

 v = +!v; 

To će biti logička vrijednost NOT v (davanje true ako v == 0 ili false ako v == 1 ). Zatim pretvorimo vraćenu logičku vrijednost u odgovarajuću cjelobrojnu reprezentaciju.

6
24 нояб. odgovor je dan 0x499602D2 24 nov. 2012-11-24 21:33 '12 u 21:33 2012-11-24 21:33

Drugi kreativni način da to učinite, s v jednakim vrijednostima, uvijek će se vratiti 0 ili 1

 v = !!v^1; 
5
02 авг. Odgovor dao Yanick Rochon 02 2011-08-02 18:47 '11 u 18:47 2011-08-02 18:47

Ako su moguće vrijednosti za v samo 0 i 1, onda je za bilo koji cijeli broj x izraz: v = Math.pow ((Math.pow (x, v) - x), v); će promijeniti vrijednost.

Znam da je ovo ružna odluka, a OP je nije tražila ... ali razmišljala sam o drugom rješenju kad sam bila u zahodu: P

4
05 авг. odgovor je dan Amit 05 aug. 2011-08-05 13:50 '11 u 13:50 2011-08-05 13:50
 v=!v; 

će raditi za v = 0 i v = 1; i prebacivanje stanja;

4
31 авг. odgovor daje učitelj 31 kolovoza. 2011-08-31 07:21 '11 at 7:21 am 2011-08-31 07:21

Nepotvrđeno, ali ako tražite logičnu, mislim da će var v = !v raditi.

Link: http://www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables

3
03 авг. odgovor dao Martin Bean 03 aug. 2011-08-03 14:18 '11 u 14:18 2011-08-03 14:18

Ako postoje samo dvije vrijednosti, kao u ovom slučaju (0, 1), mislim da je rasipno koristiti int. Umjesto toga, idite na logično i radite u bitovima. Znam što pretpostavljam, ali u slučaju prebacivanja između dvaju stanja logičan izbor je idealan izbor.

1
31 окт. Odgovor Amber 31. listopada. 2012-10-31 20:20 '12 u 20:20 2012-10-31 20:20

Pa, budući da znamo da u javascript samo da Boolean usporedba će također dati očekivani rezultat.

to jest. v = v == 0 dovoljno za to.

U nastavku je kôd za ovo:

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

Nadam se da vam ovo pomaže :)

1
04 окт. odgovor je dao Vikash Pandey 04 okt. 2016-10-04 10:27 '16 u 10:27 sati 2016-10-04 10:27
 v = !v * 1 

množenjem s 1 za pretvaranje boolea u broj

-1
28 окт. JVM odgovor 28. listopada 2017-10-28 01:12 '17 u 1:12 2017-10-28 01:12