Ich habe eine sehr lange bedingte Aussage wie die folgende:
if(test.type == 'itema' || test.type == 'itemb' || test.type == 'itemc' || test.type == 'itemd'){
// do something.
}
Ich habe mich gefragt, ob ich diesen Ausdruck / diese Aussage in eine präzisere Form umgestalten könnte.
Irgendeine Idee, wie dies erreicht werden kann?
javascript
if-statement
FlyingCat
quelle
quelle
in
?||
. (2)switch
Aussagen. (3) Regex. (4)~
. jsperf.com/if-statements-test-techsinAntworten:
Fügen Sie Ihre Werte in ein Array ein und überprüfen Sie, ob sich Ihr Element im Array befindet:
Wenn ein von Ihnen unterstützter Browser nicht über die
Array#includes
Methode verfügt, können Sie diese Polyfüllung verwenden .Kurze Erklärung der
~
Tilde-Verknüpfung:Anstatt zu überprüfen, ob das Ergebnis von
indexOf
ist>= 0
, gibt es eine nette kleine Verknüpfung:Hier ist die Geige: http://jsfiddle.net/HYJvK/
Wie funktioniert das? Wenn ein Element im Array gefunden wird, wird
indexOf
sein Index zurückgegeben. Wenn der Artikel nicht gefunden wurde, wird er zurückgegeben-1
. Ohne zu sehr ins Detail zu gehen,~
ist der ein bitweiser NOT-Operator , der0
nur für zurückgibt-1
.Ich verwende gerne die
~
Verknüpfung, da sie prägnanter ist als ein Vergleich des Rückgabewerts. Ich wünschte, JavaScript hätte einein_array
Funktion, die einen Booleschen Wert direkt zurückgibt (ähnlich wie PHP), aber das ist nur Wunschdenken ( Update: das tut es jetzt. Es heißtincludes
. Siehe oben). Beachten Sie, dass jQuery'sinArray
, während es die Methodensignatur von PHP teilt, tatsächlich die nativeindexOf
Funktionalität nachahmt (was in verschiedenen Fällen nützlich ist, wenn der Index genau das ist, wonach Sie wirklich suchen).Wichtiger Hinweis: Die Verwendung der Tilde-Verknüpfung scheint kontrovers diskutiert zu werden, da einige vehement der Ansicht sind, dass der Code nicht klar genug ist und unter allen Umständen vermieden werden sollte (siehe die Kommentare zu dieser Antwort). Wenn Sie ihre Meinung teilen, sollten Sie sich an die
.indexOf(...) >= 0
Lösung halten.Eine etwas längere Erklärung:
Ganzzahlen in JavaScript sind signiert. Dies bedeutet, dass das Bit ganz links als Vorzeichenbit reserviert ist. ein Flag, das angibt, ob die Zahl positiv oder negativ ist, wobei a
1
negativ ist.Hier sind einige positive Beispielzahlen im 32-Bit-Binärformat:
Hier sind die gleichen Zahlen, aber negativ:
Warum so komische Kombinationen für die negativen Zahlen? Einfach. Eine negative Zahl ist einfach die Umkehrung der positiven Zahl + 1; Das Addieren der negativen Zahl zur positiven Zahl sollte immer ergeben
0
.Um dies zu verstehen, führen wir eine einfache binäre Arithmetik durch.
Hier ist , wie wir hinzufügen würde
-1
zu+1
:Und hier ist , wie wir hinzufügen würde
-15
zu+15
:Wie bekommen wir diese Ergebnisse? Wenn Sie regelmäßig hinzufügen, wie wir es in der Schule gelernt haben: Sie beginnen in der Spalte ganz rechts und addieren alle Zeilen. Wenn die Summe größer ist als die größte einstellige Zahl (die dezimal
9
, aber binär ist1
), übertragen wir den Rest in die nächste Spalte.Wie Sie feststellen werden, hat die Spalte ganz rechts, die nicht alle
0
s ist, beim Hinzufügen einer negativen Zahl zu ihrer positiven Zahl immer zwei1
s, was zusammen ergibt2
. Die binäre Darstellung von zwei Wesen10
tragen wir1
in die nächste Spalte und setzen ein0
für das Ergebnis in die erste Spalte. Alle anderen Spalten auf der linken Seite haben nur eine Zeile mit einem1
, so dass sich die1
aus der vorherigen Spalte übertragenen Werte wieder summieren2
, was sich dann überträgt ... Dieser Vorgang wiederholt sich, bis wir zur Spalte ganz links gelangen, wo Das1
, was übertragen werden soll, kann nirgendwo hingehen, also läuft es über und geht verloren, und wir haben0
überall s übrig .Dieses System heißt 2's Complement . Mehr dazu lesen Sie hier:
2's Komplementdarstellung für vorzeichenbehaftete Ganzzahlen .
Jetzt, da der Crash-Kurs im 2er-Komplement beendet ist, werden Sie feststellen, dass dies
-1
die einzige Zahl ist, deren binäre Darstellung1
überall ist.Mit dem
~
bitweisen NOT-Operator werden alle Bits in einer bestimmten Zahl invertiert. Der einzige Weg, um0
vom Invertieren aller Bits zurück zu kommen, besteht darin, mit1
's all across' zu beginnen.Das alles war also eine langatmige Art zu sagen,
~n
die nur zurückkehren wird,0
wenn es son
ist-1
.quelle
!== -1
auf irgendeine denkbare Weise? Ist eine explizite boolesche Logik nicht angemessener als die implizite Verwendung der Falschheit von Null?!= -1
.Sie können die switch-Anweisung mit fall thru verwenden:
quelle
||
) unter Chrome. Siehe jsperf.com/if-statements-test-techsinVerwenden der Wissenschaft: Sie sollten das tun, was idfah gesagt hat, und dies für die schnellste Geschwindigkeit, während Sie den Code kurz halten:
Dies ist schneller als
~
Methodehttp://jsperf.com/if-statements-test-techsin (Oberer Satz: Chrome, unterer Satz: Firefox)
Fazit :
Wenn Möglichkeiten sind wenige , und Sie wissen , dass bestimmte diejenigen häufiger auftreten, als Sie maximale Performance erhalten
if ||
,switch fall through
undif(obj[keyval])
.Wenn es viele Möglichkeiten gibt und eine davon die am häufigsten auftretende sein könnte, können Sie mit anderen Worten nicht wissen, welche am wahrscheinlichsten auftritt, als wenn Sie die meiste Leistung aus der Objektsuche ziehen
if(obj[keyval])
undregex
ob dies passt.http://jsperf.com/if-statements-test-techsin/12
Ich werde aktualisieren, wenn etwas Neues auftaucht.
quelle
switch case
ist das die schnellste Methode?if ( ...||...||...)...
obj["itemX"]
ist extrem schnell, wenn n groß ist. Grundsätzlich hängt es vom Kontext ab, was schnell ist. Habe Spaß.Wenn Sie mit Zeichenfolgen vergleichen und ein Muster vorhanden ist, sollten Sie reguläre Ausdrücke verwenden.
Andernfalls wird Ihr Code vermutlich nur verschleiert, wenn Sie versuchen, ihn zu verkürzen. Ziehen Sie in Betracht, die Linien einfach zu umbrechen, um sie hübsch zu machen.
quelle
(test.type == 'itemf' && foo.mode == 'detailed')
)Die Verwendung eines Objekts als assoziatives Array ist eine ziemlich häufige Sache, aber da JavaScript keine native Menge hat, können Sie Objekte auch als billige Mengen verwenden.
quelle
if
Die Bedingung der Anweisung von @dcarson OP benötigt 78 Zeichen, wenn Sie alle Leerzeichen entfernen. Meins braucht 54, wenn du es so schreibst :test.type in {"itema":1,"itemb":1,"itemc":1,"itemd":1}
. Grundsätzlich verwendet er vier Zeichen für jeweils zwei Minen für jeden zusätzlichen Schlüssel.oder wenn die Gegenstände nicht so einheitlich sind, dann:
quelle
Hervorragende Antworten, aber Sie könnten den Code besser lesbar machen, indem Sie einen von ihnen in eine Funktion einschließen.
Dies ist eine komplexe if-Anweisung, wenn Sie (oder eine andere Person) den Code in einem Jahr lesen und den Abschnitt durchsuchen, um zu verstehen, was passiert. Eine Aussage mit dieser Ebene der Geschäftslogik führt dazu, dass Sie einige Sekunden lang stolpern, während Sie herausfinden, was Sie testen. Wenn Sie einen Code wie diesen haben, können Sie mit dem Scannen fortfahren.
Benennen Sie Ihre Funktion explizit, damit sofort ersichtlich ist, was Sie testen, und Ihr Code einfacher zu scannen und zu verstehen ist.
quelle
// CheckIfBusinessRuleIsTrue
?Sie können alle Antworten in ein Javascript-Set einfügen und dann einfach
.contains()
das Set aufrufen .Sie müssen noch den gesamten Inhalt deklarieren, aber der Inline-Anruf wird kürzer.
Etwas wie:
quelle
Eine meiner Lieblingsmethoden, um dies zu erreichen, ist eine Bibliothek wie underscore.js ...
http://underscorejs.org/#some
quelle
contains
ist wohl eine bessere Lösung alssome
some
Hierfür muss keine Bibliothek verwendet werden: Dies ist eine Funktion des Array-Prototyps in EC5.Ein anderer oder ein anderer großartiger Weg, den ich gefunden habe, ist dieser ...
Wie Sie sehen, geht dies natürlich noch einen Schritt weiter und macht es einfach, der Logik zu folgen.
http://snook.ca/archives/javascript/testing_for_a_v
mit Operatoren wie ~ && || ((), ()) ~~ ist nur in Ordnung, wenn Ihr Code später kaputt geht. Sie werden nicht wissen, wo Sie anfangen sollen. Die Lesbarkeit ist also GROSS.
Wenn Sie müssen, können Sie es kürzer machen.
und wenn Sie invers machen wollen
quelle
Verwenden Sie einfach eine
switch
Anweisung anstelle einerif
Anweisung:Switch
funktioniert auch schneller als das Vergleichen vieler Bedingungen innerhalb einesif
quelle
Bei sehr langen Listen von Zeichenfolgen würde diese Idee einige Zeichen sparen (ohne zu sagen, dass ich sie im wirklichen Leben empfehlen würde, aber sie sollte funktionieren).
Wählen Sie ein Zeichen aus, von dem Sie wissen, dass es in Ihrem test.type nicht vorkommt, verwenden Sie es als Trennzeichen, stecken Sie es alle in eine lange Zeichenfolge und suchen Sie Folgendes:
Wenn Ihre Zeichenfolgen weiter eingeschränkt sind, können Sie sogar die Trennzeichen weglassen ...
... aber Sie müssten in diesem Fall auf Fehlalarme achten (zB würde "einbetten" in dieser Version übereinstimmen)
quelle
Erstellen Sie zur besseren Lesbarkeit eine Funktion für den Test (ja, eine einzeilige Funktion):
dann nenne es:
quelle
Ich denke, es gibt zwei Ziele beim Schreiben dieser Art von if-Bedingung.
Als solches mag # 1 manchmal die schnellste sein, aber ich werde später # 2 für eine einfache Wartung nehmen. Je nach Szenario entscheide ich mich oft für eine Variation von Walters Antwort.
Zu Beginn habe ich eine global verfügbare Funktion als Teil meiner vorhandenen Bibliothek.
und wenn ich dann tatsächlich eine if-Bedingung ausführen möchte, die Ihrer ähnlich ist, würde ich ein Objekt mit einer Liste der gültigen Werte erstellen:
Es ist nicht so schnell wie eine switch / case-Anweisung und etwas ausführlicher als einige der anderen Beispiele, aber ich werde das Objekt häufig an anderer Stelle im Code wiederverwenden, was sehr praktisch sein kann.
Huckepack auf einem der oben hergestellten jsperf-Beispiele Ich habe diesen Test und eine Variation hinzugefügt, um die Geschwindigkeiten zu vergleichen. http://jsperf.com/if-statements-test-techsin/6 Das Interessanteste, was ich bemerkt habe, ist, dass bestimmte Testkombinationen in Firefox viel schneller sind als sogar Chrome.
quelle
Dies kann mit einer einfachen for-Schleife gelöst werden:
Wir verwenden den ersten Abschnitt der for-Schleife, um die Argumente zu initialisieren, mit denen Sie übereinstimmen möchten, den zweiten Abschnitt, um die Ausführung der for-Schleife zu stoppen, und den dritten Abschnitt, um zu bewirken, dass die Schleife schließlich beendet wird.
quelle