Chcę przełączać zmienną między 0 a 1. Jeśli jest to 0, chcę ustawić ją na 1, w przeciwnym razie, jeśli jest to 1, chcę ją ustawić na 0.
Jest to tak fundamentalna operacja, że tak często piszę, chciałbym zbadać najkrótszy, najczystszy możliwy sposób. Oto moje najlepsze jak dotąd:
v = (v == 0 ? 1 : 0);
Czy możesz to poprawić?
Edycja: pytanie dotyczy tego, jak napisać powyższe stwierdzenie przy użyciu jak najmniejszej liczby znaków, zachowując jasność - dlaczego to „nie jest prawdziwe pytanie”? To nie miało być ćwiczenie w golfa kodowego, chociaż pojawiły się interesujące odpowiedzi od ludzi, którzy podchodzą do niego jako golfa - miło jest widzieć, że golf jest wykorzystywany w konstruktywny i pobudzający do myślenia sposób.
javascript
variables
coding-style
toggle
Szkło Ollie
źródło
źródło
v = +!v;
Odpowiedzi:
Możesz po prostu użyć:
Zakłada to oczywiście, że zmienna została poprawnie zainicjowana, tzn. Że ma tylko wartość 0 lub 1.
Inna metoda, która jest krótsza, ale używa mniej popularnego operatora:
Edytować:
Dla jasności; Nigdy nie podchodziłem do tego pytania jako do gry w golfa kodowego, tylko po to, aby znaleźć sposób na wykonanie zadania bez korzystania z niejasnych sztuczek, takich jak skutki uboczne operatorów.
źródło
v ^= 1
jasny, powinien przestać programować, jest to trochę trudne. Jak już wspomniano, nie jest to jeden z bardziej popularnych operatorów i nie robi tego samego, cov = v ^ 1
. Również operator oznacza coś zupełnie innego w różnych językach (VB). Tak, szybkie sprawdzenie pokaże, że jest to operator XOR i zrozumiesz, co robi, ale dla wielu może to nie być oczywiste na pierwszy rzut oka. Nie sądzę, że to oznacza, że musisz rzucić pracę.Ponieważ
0
jestfalse
wartością i1
jesttrue
wartością.Jeśli jesteś szczęśliwy w użyciu
true
ifalse
zamiast liczblub jeśli muszą to być liczby:
źródło
+
wcześniej!
. Och, to wygląda na takie brudne! ale fajnie: pswitch(v){ case 0 ...
lub jeśli (v == 0) lub jeśli v === 0. Zmieniasz jego wynik oprócz jego podejścia ....({v :+! v}).v
.+
znakiem! ¯ \ _ (ツ) _ / ¯v = (v ? 0 : 1)
tak czysty i idiomatyczny JS.v = (v + 1) % 2
a jeśli potrzebujesz przechodzić przez kolejne wartości, po prostu zmień2
dla(n + 1)
. Powiedz, że musisz zrobić cykl 0,1,2 po prostu zróbv = (v + 1) % 3
.źródło
const
zmiennej zamiast magicznych liczb 2, 3, ...++v % 3
jeśli chcesz jeździć przez 0, 1, 2Możesz napisać dla niego funkcję i używać jej w następujący sposób:
v = inv(v)
źródło
inv
funkcji: P)inv
że to opisowa nazwa?Jeśli nie obchodzi Cię żadna inna możliwość niż 1:
W powyższym przypadku v skończy się na 1, jeśli v wynosi 0, false, niezdefiniowany lub null. Zachowaj ostrożność stosując takie podejście - v będzie wynosić 0, nawet jeśli v to „witaj świecie”.
źródło
v = v ? 0 : 1
.Linie podoba
v = 1 - v
, albov ^= 1
czyv= +!v
będzie wszystko to zadanie, ale stanowią one co ja określam jako hacki. Nie są to piękne linie kodu, ale tanie sztuczki, które mają przynieść zamierzony efekt.1 - v
nie komunikuje się „przełącza wartość między 0 a 1”. To sprawia, że Twój kod jest mniej wyrazisty i wprowadza miejsce (choć małe), w którym inny programista będzie musiał przeanalizować Twój kod.Posiadanie zamiast tego funkcji podobnej do
v = toggle(v)
komunikuje intencję na pierwszy rzut oka.źródło
v=1-v
nie komunikuje przełączania?1-v
potrafi się naprawdę przełączać, ale to jedyna rzecz, którą się komunikuje. Na przykład może również komunikować linię o wartości zero wv=1
lub transformację odbicia lustrzanego na środkuv=0.5
. W tym sensie jest to względnie niejednoznaczne. Prawdą jest, że wiedza o tym, że zawszev
może być0
lub1
ogranicza jego zamierzone znaczenie, ale zmusza innych programistów (lub twoje przyszłe ja) do zrozumienia tego kontekstu, zanim będzie w stanie zrozumieć tę prostą linię. Nie możesz być dużo jaśniejszy niżv = toggle(v)
v ^= 1
jest całkowicie jasne, jeśli rozumiesz operacje logiczne, które lepiej mieć, jeśli jesteś programistą. Myślę, że to różnica między tym av=1-v
; jedna jest operacją logiczną, a druga operacją arytmetyczną, a my próbujemy przedstawić koncepcję logiczną, a nie matematyczną.v ^= 1
Ma nawet pewną dwuznaczność, ponieważ można go interpretować jako xor.( Uczciwość i integralność matematyczna - biorąc pod uwagę liczbę głosów na tę „odpowiedź” - skłoniły mnie do zredagowania tej odpowiedzi. Wstrzymałem się tak długo, jak to możliwe, ponieważ miała ona służyć jako krótki żart, a nie jakkolwiek „głęboka” wszelkie wyjaśnienia wydawały się sprzeczne z celem. Jednak komentarze wyjaśniają, że powinienem być jasny, aby uniknąć nieporozumień ).
Moja oryginalna odpowiedź:
Treść tej części specyfikacji:
oznacza, że najdokładniejszym rozwiązaniem jest:
Po pierwsze, wyznanie: I nie dostać moje funkcje delta mylić. Delta Kroneckera byłaby nieco bardziej odpowiednia, ale nie tak bardzo, jak chciałem czegoś niezależnego od domeny (delta Kroneckera jest używana głównie dla liczb całkowitych). Ale tak naprawdę nie powinienem był w ogóle używać funkcji delta, powinienem powiedzieć:
Pozwól mi wyjaśnić. Przypomnijmy, że funkcja jest potrójne, (X, Y, F) , gdzie X i Y są zestawy (zwanej domeną i codomain r) i f jest to regułą, że wyznacza pewien element Y każdego elementu X . Często napisać potrójne (X, Y, F) jako f: X → Y . Biorąc pod uwagę podzbiór X , powiedzmy A , istnieje funkcja charakterystyczna, która jest funkcją χ A : X → {0,1}(można to również traktować jako funkcję większej kodomainy, takiej jak ℕ lub ℝ). Ta funkcja jest zdefiniowana przez regułę:
χ (x) = 1 jeśli x ∈ A i χ (x) = 0 , jeżeli x ∉ .
Jeśli podoba Ci się tablica prawdy, to tabela prawda na pytanie „Czy element x od X elementem podzbioru A ?”.
Zatem z tej definicji jasno wynika, że potrzebna jest tutaj funkcja charakterystyczna, z X jakimś dużym zestawem zawierającym 0 i A = {0} . Tak powinienem był napisać.
I tak do funkcji delta. W tym celu musimy wiedzieć o integracji. Albo już to wiesz, albo nie. Jeśli nie, nic, co mogę tu powiedzieć, nie mówi o zawiłościach teorii, ale mogę streścić jedno zdanie. Środek na zbiorze X jest w istocie „to, co jest potrzebne, aby oglądalność pracę”. To znaczy, że jeśli mamy zbiór X i miarę μ na tym zbiorze, to istnieje klasa funkcji X → ℝ , zwanych funkcjami mierzalnymi, dla których wyrażenie ∫ X f dμ ma sens i jest, w pewnym sensie niejasnym, „średni” z f nad X .
Biorąc pod uwagę miarę na zestawie, można zdefiniować „miarę” dla podzbiorów tego zestawu. Odbywa się to poprzez przypisanie do podzbioru całki jego funkcji charakterystycznej (przy założeniu, że jest to funkcja mierzalna). Może to być nieskończone lub niezdefiniowane (oba są subtelnie różne).
Wokół jest wiele środków, ale tutaj są dwa ważne. Jednym z nich jest standardowa miara na linii rzeczywistej ℝ. W tym przypadku ∫ ℝ f dμ jest właściwie tym, czego uczysz się w szkole (czy rachunek wciąż jest nauczany w szkołach?): Zsumuj małe prostokąty i przyjmuj coraz mniejsze szerokości. W tej mierze miarą przedziału jest jego szerokość. Miara punktu wynosi 0.
Inną ważną miarą, która działa na dowolnym zestawie, jest tak zwana miara punktowa . Jest on zdefiniowany w taki sposób, że całka funkcji jest sumą jej wartości:
∫ X f dμ = ∑ x ∈X f (x)
Ta miara przypisuje do każdego zestawu singletonów miarę 1. Oznacza to, że podzbiór ma miarę skończoną wtedy i tylko wtedy, gdy sam jest skończony. I bardzo niewiele funkcji ma całkę skończoną. Jeśli funkcja ma całkę skończoną, musi być niezerowa tylko na policzalnej liczbie punktów. Tak więc ogromna większość funkcji, które prawdopodobnie znasz, nie ma skończonej całki w ramach tej miary.
A teraz funkcje delta. Weźmy bardzo szeroką definicję. Mamy wymierną przestrzeń (X, μ) (tak, to zestaw z miarą na nim) i element a ∈ X . „Definiujemy” funkcję delta (w zależności od a ), aby była „funkcją” δ a : X → ℝ z właściwością, że δ a (x) = 0, jeśli x ≠ a i ∫ X δ a dμ = 1 .
Najważniejszym faktem, który należy wziąć pod uwagę, jest to: funkcja delta nie musi być funkcją . To jest nie poprawnie zdefiniowane: Nie powiedziałem co Æ (a) jest.
To, co robisz w tym momencie, zależy od tego, kim jesteś. Świat tutaj dzieli się na dwie kategorie. Jeśli jesteś matematykiem, mówisz:
Jeśli nie jesteś matematykiem, powiedz:
Obrażając teraz moją publiczność, będę kontynuować.
Diraca delta zazwyczaj przyjmuje się, że funkcja delta punktu (często 0) w prostej ze standardowego środka. Więc ci, którzy narzekają w komentarzach na mój temat, nie znając moich delt, robią to, ponieważ używają tej definicji. Przepraszam: chociaż mogę się z tego wywinąć, korzystając z obrony Matematyka (spopularyzowanej przez Humpty'ego Dumpty'ego : po prostu przedefiniuj wszystko, aby było poprawne), ale złym sposobem jest użycie standardowego terminu na oznaczenie czegoś innego.
Ale jest funkcja delta, która robi to, co chcę, i jest to, czego potrzebuję tutaj. Jeśli biorę środka punkt w zbiorze X to nie jest prawdziwym funkcja δ a : X → ℝ , która spełnia kryteria dla funkcji delta. Wynika to z faktu, że szukamy funkcji X → ℝ, która jest równa zero, z wyjątkiem a i takiej, że suma wszystkich jej wartości wynosi 1. Taka funkcja jest prosta: jedyną brakującą informacją jest jej wartość przy a , i aby otrzymać sumę równą 1, po prostu przypisujemy jej wartość 1. Jest to nic innego jak funkcja charakterystyczna na {a} . Następnie:
∫ X δ a dμ = ∑ x ∈ X δ a (x) = δ a (a) = 1.
Tak więc w tym przypadku dla zestawu singletonowego funkcja charakterystyczna i funkcja delta są zgodne.
Podsumowując, istnieją tutaj trzy rodziny „funkcji”:
Drugi z nich jest najbardziej ogólnym, jak każdy z pozostałych jest przykładem nim przy użyciu środka punktową. Ale pierwsza i trzecia mają tę zaletę, że są to zawsze oryginalne funkcje. Trzeci jest w rzeczywistości szczególnym przypadkiem pierwszego, dla konkretnej rodziny domen (liczb całkowitych lub niektórych ich podzbiorów).
Wreszcie, kiedy pierwotnie napisałem odpowiedź, nie myślałem poprawnie (nie posunąłem się nawet do stwierdzenia, że byłem zdezorientowany , ponieważ mam nadzieję, że właśnie pokazałem, że wiem o czym mówię, kiedy Właściwie to najpierw myślę, po prostu niewiele myślałem). Zwykłe znaczenie delty diraca nie jest tutaj potrzebne, ale jednym z punktów mojej odpowiedzi było to, że domena wejściowa nie została zdefiniowana, więc delta Kroneckera również nie miałaby racji. Zatem najlepszą odpowiedzią matematyczną (do której dążyłem) byłaby funkcja charakterystyczna .
Mam nadzieję, że to wszystko jasne; i mam również nadzieję, że już nigdy nie będę musiał pisać matematyki używając encji HTML zamiast makr TeX!
źródło
Mógłbyś
Zmniejszenie ustawia wartość na 0 lub -1, a następnie
Math.abs
konwertuje -1 na +1.źródło
v = Math.round(Math.sin(Math.PI/(v+3)));
v = Math.round(Math.cos(Math.PI/((v*2+1)+2)-2*v));
: Dv = 1
to,v = Math.Abs(-1)
co jest +1. Jeśliv = 0
więcv = Math.Abs(-0)
to jest 0.ogólnie za każdym razem, gdy trzeba przełączać się między dwiema wartościami, można po prostu odjąć bieżącą wartość od sumy dwóch wartości przełączania:
źródło
v
zostanie uszkodzony, nagle zacznie się przełączać między dwiema różnymi wartościami. (Tylko coś do rozważenia ...)v
normalnie jest używany do naprzemiennego wykonywania dwóch stanów z listy trzech lub więcej stanów, wówczas uszkodzeniev
może spowodować naprzemienne wykonywanie przez program dwóch zupełnie różnych stanów - może to spowodować nieoczekiwane i niepożądane wyniki. Lekcja, którą należy wyciągnąć z tego jest następująca: Zawsze sprawdzaj wiarygodność swoich danych.Jeśli musi to być liczba całkowita 1 lub 0, to sposób, w jaki to robisz, jest w porządku, chociaż nawiasy nie są potrzebne. Jeśli te mają być używane jako booleany, możesz po prostu zrobić:
źródło
Wystarczy !
źródło
v = (v==0 ? 1 : 0);
” . Wszyscy inni znajdują różne sposoby gry w golfa; i nie odpowiadając na pytanie. Właśnie dlatego głosowałem za tą odpowiedzią.Lista rozwiązań
Są trzy rozwiązania, które chciałbym zaproponować. Wszystkie z nich przekształcić dowolną wartość
0
(jeśli1
,true
itd.) Lub1
(jeśli0
,false
,null
itd.):v = 1*!v
v = +!v
v = ~~!v
i jeden dodatkowy, już wspomniany, ale sprytny i szybki (chociaż działa tylko dla
0
s i1
s):v = 1-v
Rozwiązanie 1
Możesz użyć następującego rozwiązania:
To najpierw przekształci liczbę całkowitą na przeciwną wartość logiczną (
0
naTrue
i dowolną inną wartość naFalse
), a następnie potraktuje ją jako liczbę całkowitą podczas mnożenia1
. W rezultacie0
zostaną przekonwertowane na1
dowolną inną wartość0
.Jako dowód zobacz to jsfiddle i podaj wszelkie wartości, które chcesz przetestować: jsfiddle.net/rH3g5/
Wyniki są następujące:
-123
zamieni się na liczbę całkowitą0
,-10
zamieni się na liczbę całkowitą0
,-1
zamieni się na liczbę całkowitą0
,0
zamieni się na liczbę całkowitą1
,1
zamieni się na liczbę całkowitą0
,2
zamieni się na liczbę całkowitą0
,60
zamieni się na liczbę całkowitą0
,Rozwiązanie 2
Jak zauważył mblase75, jAndy miał inne rozwiązanie, które działa jak moje:
Najpierw robi też wartość logiczną z pierwotnej wartości, ale używa
+
zamiast1*
konwertować ją na liczbę całkowitą. Wynik jest dokładnie taki sam, ale notacja jest krótsza.Rozwiązanie 3
Innym podejściem jest użycie
~~
operatora:Jest to dość rzadkie i zawsze zamienia się na liczbę całkowitą z wartości logicznej.
źródło
+
aby przekonwertować ją na liczbę, więc+!v
jest to odpowiednik twojego rozwiązania (rozwiązanie jAndy w komentarzach PO).1*
można zastąpić+
przy próbie konwersji wartości logicznej na liczbę całkowitą. Wszystko inne w mojej odpowiedzi pozostaje takie samo. Odpowiedź Andy'ego jest poprawna, ale moja jest bardziej szczegółowa. Dodam jego / jej rozwiązanie do mojej odpowiedzi.Podsumowując inną odpowiedź, komentarz i moją własną opinię, sugeruję połączenie dwóch rzeczy:
Oto funkcja, którą możesz umieścić w bibliotece lub zawinąć we wtyczkę dla innego środowiska JavaScript.
A użycie jest po prostu:
Zalety to:
źródło
function toggle(i){ return i == 0 ? 1 : 0 }
?Nie wiem, dlaczego chcesz budować własne booleany? Lubię funky składnie, ale dlaczego nie napisać zrozumiałego kodu?
To nie jest najkrótszy / najszybszy, ale najczystszy (i czytelny dla wszystkich) to znany stan if / else:
Jeśli chcesz być naprawdę jasny, powinieneś użyć do tego boolanów zamiast liczb. Są wystarczająco szybkie w większości przypadków. W przypadku booleanów możesz po prostu użyć tej składni, która wygra w skrócie:
źródło
=== 0
. Przy przykładowym wprowadzeniu7
poprawnego wyniku jest0
, ale to da wynik1
.Inna forma Twojego oryginalnego rozwiązania:
EDYCJA: Dzięki TehShrike i Guffa za wskazanie błędu w moim oryginalnym rozwiązaniu.
źródło
'opacity:'+true
a skończysz naopacity:true
zamiastopacity:1
.Uściśliłbym to.
Co
v
znaczyNa przykład, gdy v to jakiś stan. Utwórz status obiektu. W DDD obiekt wartości.
Zaimplementuj logikę w tym obiekcie wartości. Następnie możesz napisać kod w bardziej funkcjonalny sposób, który jest bardziej czytelny. Przełączanie statusu można wykonać, tworząc nowy status w oparciu o bieżący status. Twoja instrukcja / logika if jest następnie enkapsulowana w twoim obiekcie, co możesz zabronić. ValueObject jest zawsze niezmienny, więc nie ma tożsamości. Aby zmienić jego wartość, musisz stworzyć nową.
Przykład:
źródło
Kolejny sposób to zrobić:
źródło
Brakuje:
Działa również jako okrągły robin:
Lub
Urok tego ostatniego rozwiązania, działa również ze wszystkimi innymi wartościami.
W bardzo szczególnym przypadku, na przykład w celu uzyskania (zmieniającej się) wartości
undefined
, ten wzorzec może być pomocny:źródło
Ponieważ jest to JavaScript, możemy użyć unary
+
do konwersji na int:Będzie to logiczne
NOT
dla wartościv
(podającejtrue
jeśliv == 0
lubfalse
jeśliv == 1
). Następnie przekształcamy zwróconą wartość logiczną na odpowiadającą jej liczbę całkowitą.źródło
Tylko dla kopnięć:
v = Math.pow(v-1,v)
przełącza się między 1 a 0.źródło
Jeszcze jeden:
v=++v%2
(w C byłoby to proste
++v%=2
)ps. Tak, wiem, że to podwójne przypisanie, ale to tylko surowe przepisanie metody C.
źródło
++
operatora (to nie jest wartość). Co do tegov=++v%2
, modyfikujeszv
dwa razy. Nie wiem, czy jest to dobrze zdefiniowane w JavaScript, ale nie jest to konieczne.v = (v+1) % 2
.c++
tym jest - ponieważ operator wstępnej inkrementacji ma wyższy priorytet i modyfikuje zmienną „na miejscu”, dzięki czemu może być używana jako wartość. Myślę, że implementacja JS++
jest taka, że nie można jej traktować jak wartości: / Tak, to jest zbędne, ale starałem się pokazać tylko inną metodę - są już opublikowane lepsze rozwiązania :)Jeśli masz gwarancję, że twoja wartość to 1 lub 0, możesz użyć:
źródło
zdefiniuj tablicę {1,0}, ustaw v na v [v], dlatego v o wartości 0 staje się 1 i vice versa.
źródło
Inny kreatywny sposób na zrobienie tego, z
v
równością dowolnej wartości, zawsze powróci0
lub1
źródło
!!
skutkują niczym w logice matematycznej, którą można!!!!
tam umieścić i będą takie same, ale będą skutkować 4 niepotrzebnymi operacjami!!
rzuci na bool.!!(1) === true
oraz!!(0) === false
v = Boolean(v^1)
, że byłby bardziej informacyjny, dzięki za wyjaśnienie - nie myślałem o castingu!
przekształci go w boolean. Dodanie kolejnego!
spowoduje zanegowanie tego boolean. Rzutowanie jest tutaj niejawne, a efekt końcowy działa. Nie ma potrzeby -1.Jeśli możliwe wartości v to tylko 0 i 1, to dla dowolnej liczby całkowitej x wyrażenie: v = Math.pow ((Math.pow (x, v) - x), v); zmieni wartość.
Wiem, że to brzydkie rozwiązanie i OP nie szukał tego ... ale myślałem o innym rozwiązaniu, kiedy byłem w toalecie: P
źródło
Nie przetestowano, ale jeśli szukasz boolean, myślę,
var v = !v
że zadziała.Odniesienie: http://www.jackfranklin.co.uk/blog/2011/05/a-better-way-to-reverse-variables
źródło
będzie działać dla v = 0 i v = 1; i przełączać stan;
źródło
Jeśli są tylko dwie wartości, tak jak w tym przypadku (0, 1), uważam, że marnowanie int jest niepotrzebne. Raczej idź na boolean i pracuj w bitach. Wiem, że zakładam, ale w przypadku przełączania między dwoma stanami wartość logiczna wydaje się idealnym wyborem.
źródło
Cóż, jak wiemy, że w javascript tylko porównanie boolowskie da również oczekiwany wynik.
to znaczy
v = v == 0
wystarczy do tego.Poniżej znajduje się kod do tego:
JSFiddle: https://jsfiddle.net/vikash2402/83zf2zz0/
Mam nadzieję, że to ci pomoże :)
źródło
true
ifalse
. Możesz użyćv == 0
do ustalenia wartości zmiennej w warunku, ale jeśli chcesz użyć wartości 0 lub 1, musisz użyć czegoś podobnegov == 0 ? 0 : 1
lubNumber(v)
uzyskać. (Możesz także użyćv = !v;
do przełączania międzytrue
ifalse
.)Wpisz typ rzutowania Odwróconą wartość logiczną na Liczba, która jest pożądanym wynikiem.
źródło