Mam bardzo długą instrukcję warunkową, taką jak ta:
if(test.type == 'itema' || test.type == 'itemb' || test.type == 'itemc' || test.type == 'itemd'){
// do something.
}
Zastanawiałem się, czy mógłbym zmienić to wyrażenie / oświadczenie w bardziej zwięzłą formę.
Masz pomysł, jak to osiągnąć?
javascript
if-statement
FlyingCat
źródło
źródło
in
?||
. (2)switch
oświadczenia. (3) wyrażenie regularne. (4)~
. jsperf.com/if-statements-test-techsinOdpowiedzi:
Umieść swoje wartości w tablicy i sprawdź, czy pozycja znajduje się w tablicy:
Jeśli obsługiwana przeglądarka nie ma tej
Array#includes
metody, możesz użyć tego wypełnienia .Krótkie wyjaśnienie
~
skrótu tyldy:Zamiast sprawdzać, czy wynik
indexOf
jest>= 0
, istnieje ładny mały skrót:Oto skrzypce: http://jsfiddle.net/HYJvK/
Jak to działa? Jeśli element zostanie znaleziony w tablicy,
indexOf
zwraca jego indeks. Jeśli przedmiot nie został znaleziony, wróci-1
. Bez wchodzenia w zbyt wiele szczegółów~
jest operatorem bitowym NOT , który zwróci0
tylko dla-1
.Lubię używać
~
skrótu, ponieważ jest bardziej zwięzły niż porównanie wartości zwracanej. Chciałbym, żeby JavaScript miałin_array
funkcję, która zwraca bezpośrednio wartość logiczną (podobną do PHP), ale to tylko pobożne życzenia ( aktualizacja: teraz ma. Nazywa sięincludes
. Patrz powyżej). Zauważ, że jQueryinArray
, podczas udostępniania sygnatury metody PHP, w rzeczywistości naśladuje natywnąindexOf
funkcjonalność (co jest przydatne w różnych przypadkach, jeśli indeks jest tym, czego naprawdę szukasz).Ważna uwaga: używanie skrótu tyldy wydaje się być przedmiotem kontrowersji, jak niektórzy zaciekle uważają, że kod nie jest wystarczająco jasny i należy go unikać za wszelką cenę (patrz komentarze do tej odpowiedzi). Jeśli podzielasz ich zdanie, powinieneś trzymać się
.indexOf(...) >= 0
rozwiązania.Trochę dłuższe wyjaśnienie:
Liczby całkowite w JavaScript są podpisywane, co oznacza, że skrajny lewy bit jest zarezerwowany jako bit znaku; flaga wskazująca, czy liczba jest dodatnia czy ujemna, z a
1
czym jest ujemna.Oto kilka przykładowych liczb dodatnich w 32-bitowym formacie binarnym:
Oto te same liczby, ale ujemne:
Skąd takie dziwne kombinacje liczb ujemnych? Prosty. Liczba ujemna jest po prostu odwrotnością liczby dodatniej + 1; dodanie liczby ujemnej do liczby dodatniej powinno zawsze dawać
0
.Aby to zrozumieć, zróbmy prostą arytmetykę binarną.
Oto, jak dodalibyśmy
-1
do+1
:A oto jak dodalibyśmy
-15
do+15
:Jak otrzymujemy te wyniki? Robiąc regularne dodawanie, tak jak nas uczono w szkole: zaczynasz od skrajnej prawej kolumny i dodajesz wszystkie wiersze. Jeśli suma jest większa niż największa liczba jednocyfrowa (która w systemie dziesiętnym to
9
, ale w systemie dwójkowym to1
), resztę przenosimy do następnej kolumny.Teraz, jak zauważysz, po dodaniu liczby ujemnej do jej liczby dodatniej, skrajna prawa kolumna, która nie zawiera wszystkich
0
s, zawsze będzie miała dwa1
s, co po dodaniu da w wyniku2
. Binarną reprezentację dwóch bytów10
przenosimy1
do następnej kolumny i umieszczamy jako0
wynik w pierwszej kolumnie. Wszystkie inne kolumny po lewej mają tylko jeden wiersz z literą a1
, więc1
przeniesione z poprzedniej kolumny ponownie sumują się do2
, co następnie przenosi ... Ten proces powtarza się, aż dojdziemy do skrajnej lewej kolumny, gdzie to, co1
ma zostać przeniesione, nie ma dokąd pójść, więc przepełnia się i gubi, a my zostajemy z nami0
s na całej długości.Ten system nazywa się dopełnieniem 2 . Możesz przeczytać więcej na ten temat tutaj:
Reprezentacja uzupełnienia 2 dla podpisanych liczb całkowitych .
Teraz, gdy błyskawiczny kurs dopełniania 2 się skończył, zauważysz, że
-1
jest to jedyna liczba, której reprezentacja binarna to1
całą szerokość.Używając
~
bitowego operatora NOT, wszystkie bity w danej liczbie są odwracane. Jedynym sposobem0
powrotu do odwracania wszystkich bitów jest rozpoczęcie od1
wszystkich.Więc to wszystko było rozwlekłym sposobem stwierdzenia, że
~n
powróci tylko0
wtedy, gdy takn
jest-1
.źródło
!== -1
w jakikolwiek możliwy sposób? Czy jawna logika boolowska nie jest bardziej odpowiednia niż niejawne użycie błędu zero?!= -1
.Możesz użyć instrukcji switch z fall thru:
źródło
||
) w Chrome. Zobacz jsperf.com/if-statements-test-techsinKorzystanie z nauki: powinieneś zrobić to, co powiedział idfah, a to dla największej szybkości przy zachowaniu krótkiego kodu:
TO SZYBCIEJ NIŻ
~
METODAhttp://jsperf.com/if-statements-test-techsin (górny zestaw: Chrome, dolny zestaw: Firefox)
Wniosek:
Jeśli możliwości są nieliczne i wiesz, że niektóre z nich są bardziej prawdopodobne niż można uzyskać maksymalną wydajność
if ||
,switch fall through
orazif(obj[keyval])
.Jeśli możliwości jest wiele , a każda z nich może być najbardziej występująca, innymi słowy, nie możesz wiedzieć, która z nich jest najbardziej prawdopodobna, niż uzyskujesz największą wydajność z wyszukiwania obiektów
if(obj[keyval])
iregex
czy to pasuje.http://jsperf.com/if-statements-test-techsin/12
zaktualizuję, jeśli pojawi się coś nowego.
źródło
switch case
jest najszybsza metoda?if ( ...||...||...)...
obj["itemX"]
jest niezwykle szybki, jeśli n jest duże. Zasadniczo to, co jest szybkie, zależy od kontekstu. Baw się dobrze.Jeśli porównujesz ciągi i istnieje wzorzec, rozważ użycie wyrażeń regularnych.
W przeciwnym razie podejrzewam, że próba skrócenia go spowoduje tylko zaciemnienie kodu. Rozważ po prostu zawinięcie linii, aby było ładnie.
źródło
(test.type == 'itemf' && foo.mode == 'detailed')
)Używanie obiektu jako tablicy asocjacyjnej jest dość powszechne, ale ponieważ JavaScript nie ma natywnego zestawu, możesz używać obiektów jako tanich zestawów.
źródło
if
instrukcji @dcarson OP zajmuje 78 znaków, jeśli usuniesz wszystkie białe znaki. Kopalnia zajmuje 54 jeśli piszesz to tak:test.type in {"itema":1,"itemb":1,"itemc":1,"itemd":1}
. Zasadniczo używa czterech znaków na każde dwa użycie min dla każdego dodatkowego klucza.lub jeśli przedmioty nie są tak jednolite, to:
źródło
Doskonałe odpowiedzi, ale możesz uczynić kod znacznie bardziej czytelnym, opakowując jedną z nich w funkcję.
Jest to skomplikowane, jeśli stwierdzisz, że kiedy ty (lub ktoś inny) przeczytasz kod za lata, będziesz skanować, aby znaleźć sekcję, aby zrozumieć, co się dzieje. Stwierdzenie z takim poziomem logiki biznesowej spowoduje, że przez kilka sekund będziesz się potykać, gdy będziesz analizować to, co testujesz. Gdzie taki kod, pozwoli ci kontynuować skanowanie.
Nazwij swoją funkcję jawnie, aby od razu było wiadomo, co testujesz, a kod będzie znacznie łatwiejszy do zeskanowania i zrozumienia.
źródło
// CheckIfBusinessRuleIsTrue
?Możesz umieścić wszystkie odpowiedzi w zestawie Javascript, a następnie po prostu zadzwonić
.contains()
do zestawu.Nadal musisz zadeklarować całą zawartość, ale wywołanie inline będzie krótsze.
Coś jak:
źródło
Jednym z moich ulubionych sposobów osiągnięcia tego jest biblioteka, taka jak underscore.js ...
http://underscorejs.org/#some
źródło
contains
jest prawdopodobnie lepszym rozwiązaniem niżsome
some
to funkcja prototypu Array w EC5.w inny lub inny niesamowity sposób, który znalazłem, to ...
oczywiście, jak widać, idzie to o krok dalej i ułatwia ich stosowanie.
http://snook.ca/archives/javascript/testing_for_a_v
używając operatorów takich jak ~ && || ((), ()) ~~ jest w porządku tylko wtedy, gdy twój kod zepsuje się później. Nie będziesz wiedział, od czego zacząć. Czytelność jest więc DUŻA.
jeśli musisz, możesz go skrócić.
a jeśli chcesz zrobić odwrotność
źródło
Po prostu użyj
switch
oświadczenia zamiastif
oświadczenia:Switch
działa również szybciej niż porównywanie wielu warunków warunkowych w ramachif
źródło
W przypadku bardzo długich list ciągów ten pomysł pozwoliłby zaoszczędzić kilka znaków (nie mówiąc, że poleciłbym go w prawdziwym życiu, ale powinien działać).
Wybierz znak, o którym wiesz, że nie pojawi się w twoim teście. Typ, użyj go jako separatora, umieść je wszystkie w jednym długim ciągu i wyszukaj, że:
Jeśli twoje ciągi są bardziej ograniczone, możesz nawet pominąć ograniczniki ...
... ale w takim przypadku należy uważać na fałszywe alarmy (np. „embite” będzie pasować w tej wersji)
źródło
Dla czytelności utwórz funkcję do testu (tak, funkcja jednowierszowa):
to nazwij to:
źródło
Myślę, że przy pisaniu tego rodzaju warunku if są dwa cele.
W związku z tym czasami numer 1 może być najszybszy, ale później wezmę numer 2 dla łatwej konserwacji. W zależności od scenariusza często wybieram wariację odpowiedzi Waltera.
Na początek mam globalnie dostępną funkcję w ramach mojej istniejącej biblioteki.
a wtedy, gdy faktycznie chcę uruchomić warunek if podobny do twojego, utworzę obiekt z listą prawidłowych wartości:
Nie jest tak szybka jak instrukcja switch / case i trochę bardziej szczegółowa niż niektóre inne przykłady, ale często ponownie używam obiektu w innym miejscu w kodzie, co może być całkiem przydatne.
Podłączając jedną z próbek jsperf wykonanych powyżej, dodałem ten test i odmianę do porównania prędkości. http://jsperf.com/if-statements-test-techsin/6 Najbardziej interesującą rzeczą, jaką zauważyłem, jest to, że niektóre kombinacje testowe w Firefoksie są znacznie szybsze niż nawet Chrome.
źródło
Można to rozwiązać za pomocą prostej pętli for:
Używamy pierwszej sekcji pętli for do zainicjowania argumentów, które chcesz dopasować, drugiej sekcji do zatrzymania wykonywania pętli for, a trzeciej sekcji do spowodowania zakończenia pętli.
źródło