Zum Beispiel so etwas:
var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0
Gibt es einen besseren Weg, das zu schreiben? Auch hier suche ich keine Antwort auf die genaue Frage oben, sondern nur ein Beispiel dafür, wann Sie möglicherweise Operanden in ternären Operatorausdrücken wiederholt haben ...
javascript
conditional-operator
user1354934
quelle
quelle
if
und nicht einif/else
just an example of when you might have repeated things in the ternary
Wiederholen Sie berechnete Ausdrücke nicht. Dafür sind Variablen da.3
nicht der Index0
von istsomeArray
?Math.max(someArray.indexOf(3), 0)
stattdessen verwenden?Antworten:
Persönlich finde ich, dass der beste Weg, dies zu tun, immer noch die gute alte
if
Aussage ist:quelle
if
Anweisung anstelle eines ternären Ergebnisses . Ternäre Anweisungen sind immer noch häufig nützlich, um eine Auswahl als Teil eines Ausdrucks durchzuführen.value
nach der ersten Zeile gespeicherte Wert ist ein Zwischenwert. Es enthält nicht den richtigen Wert, der dann in der nächsten Zeile festgelegt wird und somit ein Zwischenprodukt ist. Erstif
wenn die Aussage abgeschlossen ist,value
enthält sie den richtigen Wert. Das Ternär im OP ist eine bessere Lösung als dies, da es niemals in einen Zwischenzustand übergeht.value
hier technisch mutiert ist, was ich zu vermeiden versuche.Code sollte lesbar sein, also sollte Prägnanz nicht bedeuten, dass Sie um jeden Preis knapp sind - dafür sollten Sie erneut auf https://codegolf.stackexchange.com/ posten - stattdessen würde ich empfehlen, eine zweite lokale Variable mit dem Namen
index
zu verwenden, um die Lesbarkeit zu maximieren ( bei minimalen Laufzeitkosten stelle ich auch fest):Aber wenn Sie diesen Ausdruck wirklich reduzieren möchten, weil Sie ein grausamer Sadist gegenüber Ihren Mitarbeitern oder Projektmitarbeitern sind, dann sind hier 4 Ansätze, die Sie verwenden können:
1: Temporäre Variable in einer
var
AnweisungSie können die
var
Fähigkeit der Anweisung verwenden, eine zweite temporäre Variable zu definieren (und zuzuweisen),index
wenn sie durch Kommas getrennt wird:2: Selbstausführende anonyme Funktion
Eine weitere Option ist eine selbstausführende anonyme Funktion:
3: Kommaoperator
Es gibt auch den berüchtigten "Komma-Operator", den JavaScript unterstützt und der auch in C und C ++ vorhanden ist.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Sie können es verwenden, um Nebenwirkungen einzuführen, in diesem Fall indem Sie Folgendes neu zuweisen
value
:Dies funktioniert, weil
var value
zuerst interpretiert wird (da es sich um eine Anweisung handelt), dann dievalue
Zuordnung ganz links, ganz innen und dann die rechte Hand des Kommaoperators und dann der ternäre Operator - alles legales JavaScript.4: Neuzuweisung in einem Unterausdruck
Der Kommentator @IllusiveBrian wies darauf hin, dass die Verwendung des Komma-Operators (im vorherigen Beispiel) nicht erforderlich ist, wenn die Zuweisung an
value
als Unterausdruck in Klammern verwendet wird:Beachten Sie, dass die Verwendung von Negativen in logischen Ausdrücken härter sein können für den Menschen zu folgen - so alle oben genannten Beispiele kann durch Änderung für das Lesen vereinfacht werden
idx !== -1 ? x : y
zuidx == -1 ? y : x
:quelle
indefOf
var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
anstatt ein Komma zu verwenden.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
weil ist nur ein Parameter.Für Zahlen
Sie können die
Math.max()
Funktion verwenden.Dadurch bleiben die Grenzen des Ergebnisses
0
bis zum ersten Ergebnis größer als in0
diesem Fall. Und wenn das Ergebnis vonindexOf
ist-1
, wird 0 zurückgegeben, da es größer als ist-1
.Für Boolesche und Boolesche-y-Werte
Für JS gibt es keine allgemeine Regel AFAIK, insbesondere weil, wie falsche Werte ausgewertet werden.
Aber wenn Ihnen die meiste Zeit etwas helfen kann, ist der Operator (
||
):Sie müssen damit sehr vorsichtig sein, da in Ihrem ersten Beispiel zurückgegeben werden
indexOf
kann0
und wenn Sie bewerten0 || -1
, wird es zurückgegeben,-1
weil0
es sich um einen falschen Wert handelt.quelle
3
oder"y"
nicht ?0
someArray
Math.max
Beispiel?indexOf
Gibt den Index des Elements zurück. Wenn das Element nicht gefunden wird, wird -1 zurückgegeben. Sie haben also die Möglichkeit, eine Zahl von -1 bis zur Länge der Zeichenfolge zu erhalten.Math.max
Setzen Sie dann einfach die Grenzen von 0 bis zur Länge, um die Chance zu beseitigen ein -1,0
des übereinstimmenden Elements innerhalb des Arrays anzeigen oder auf0
setzen könnteMath.max()
; oder beim bedingten Bediener bei OP. Überlegen Sievar value = Math.max( ["y"].indexOf("y"), 0 )
. Wie bestimmen Sie, welche0
zurückgegeben wird?0
an denMath.max()
Aufruf übergeben oder den0
Index"y"
innerhalb des Arrays widerspiegeln ?Nicht wirklich, verwenden Sie einfach eine andere Variable.
Ihr Beispiel verallgemeinert sich auf so etwas.
Sie testen einen berechneten Wert und weisen diesen Wert dann einer Variablen zu, wenn sie ein Prädikat übergibt. Die Möglichkeit, eine Neuberechnung des berechneten Werts zu vermeiden, liegt auf der Hand: Verwenden Sie eine Variable, um das Ergebnis zu speichern.
Ich verstehe, was du meinst - es scheint, dass es einen Weg geben sollte, der etwas sauberer aussieht. Aber ich denke, das ist der beste Weg (idiomatisch), dies zu tun. Wenn Sie dieses Muster aus irgendeinem Grund häufig in Ihrem Code wiederholt haben, können Sie eine kleine Hilfsfunktion schreiben:
quelle
EDIT: Hier ist es, der Vorschlag für Nullary-Coalescing jetzt in JavaScript!
Verwenden
||
const result = a ? a : 'fallback value';
ist äquivalent zu
const result = a || 'fallback value';
Wenn Gießen
a
aufBoolean
Rückkehrfalse
,result
wird zugewiesen'fallback value'
, andernfalls den Werta
.Achten Sie auf den Randfall
a === 0
, der (falsch) geworfen wirdfalse
undresult
wird'fallback value'
. Verwenden Sie solche Tricks auf eigenes Risiko.PS. Sprachen wie Swift haben den Null-Koaleszenz- Operator (
??
), der einem ähnlichen Zweck dient. Zum Beispiel würden Sie in Swift schreiben,result = a ?? "fallback value"
was JavaScript ziemlich nahe kommtconst result = a || 'fallback value';
quelle
indexOf()
, in diesem Muster jedoch nicht verwendet werden kann.||
funktioniert in JavaScript? Wenn ich Sie richtig verstehe, funktioniert es anders als viele andere Primärsprachen (ich denke hauptsächlich an C und seine Nachkommen [C ++, Java usw.]). Auch wenn dies||
in JavaScript wirklich so funktioniert, würde ich von der Verwendung abraten Tricks wie diese, bei denen die Betreuer spezielle Macken über die Sprache kennen müssen. Obwohl dieser Trick cool ist, würde ich ihn als schlechte Übung betrachten.-1
. Auch hier kann ich nicht für JavaScript und seine Macken sprechen, aber im Allgemeinen-1
wäre es ein wahrer Wert, kein falscher, und daher würde Ihre Antwort im Fall der Frage nicht funktionieren und sicherlich nicht im allgemeinen Fall, sondern nur in einem bestimmten Fall ( aber häufig genug) Unterfall.Verwenden Sie ein Refactoring für Extraktvariablen :
Es ist noch besser mit
const
stattvar
. Sie können auch eine zusätzliche Extraktion durchführen:In der Praxis verwendet aussagekräftigeren Namen als
index
,condition
undvalue
.quelle
Sie suchen wahrscheinlich nach einem Koaleszenzoperator. Glücklicherweise können wir den
Array
Prototyp nutzen, um einen zu erstellen:Dies könnte durch Hinzufügen eines Parameters zur Funktion weiter auf Ihren Fall verallgemeinert werden:
quelle
for (let x in ['b','c']) console.log(x);
druckt0
,1
,"coalesce"
.Ich persönlich bevorzuge zwei Varianten:
Rein wenn, wie @slebetman vorgeschlagen hat
Separate Funktion, die einen ungültigen Wert durch einen Standardwert ersetzt, wie in diesem Beispiel:
quelle
Ich mag die Antwort von @ slebetman. Der Kommentar darunter äußert sich besorgt darüber, dass sich die Variable in einem "Zwischenzustand" befindet. Wenn dies ein großes Problem für Sie ist, schlage ich vor, es in eine Funktion zu kapseln:
Dann ruf einfach an
Sie könnten allgemeinere Funktionen ausführen, wenn Sie sie an anderen Stellen verwenden, aber nicht überentwickeln, wenn es sich um einen ganz bestimmten Fall handelt.
Aber um ehrlich zu sein, würde ich nur als @slebetman arbeiten, wenn ich nicht von mehreren Stellen aus wiederverwenden müsste.
quelle
Es gibt zwei Möglichkeiten, wie ich Ihre Frage betrachten kann: Sie möchten entweder die Zeilenlänge reduzieren oder Sie möchten speziell vermeiden, eine Variable in einem Ternär zu wiederholen. Der erste ist trivial (und viele andere Benutzer haben Beispiele veröffentlicht):
kann (und sollte angesichts der Funktionsaufrufe) wie folgt gekürzt werden:
Wenn Sie nach einer allgemeineren Lösung suchen, die die Wiederholung einer Variablen in einem Ternär verhindert, wie folgt:
wo
foo
nur einmal erscheint. Lösungen der Form verwerfen:Wenn Sie technisch korrekt sind, aber den Punkt verfehlen, haben Sie kein Glück. Es gibt Operatoren, Funktionen und Methoden, die die von Ihnen gesuchte knappe Syntax besitzen, aber solche Konstrukte sind per Definition keine ternären Operatoren .
Beispiele:
Javascript,
||
um die RHS zurückzugeben, wenn die LHS istfalsey
:quelle
Verwenden Sie eine Hilfsfunktion:
Jetzt ist Ihr Code sehr gut lesbar und es gibt keine Wiederholung.
Die Hierarchie der Codierungsprobleme lautet:
Alle Antworten auf der Seite scheinen bisher korrekt zu sein, aber ich denke, meine Version hat die höchste Klarheit, was wichtiger ist als Prägnanz. Wenn Sie die Hilfsfunktion nicht zählen, da sie wiederverwendet werden kann, ist sie auch die prägnanteste. Der etwas ähnliche Vorschlag, eine Hilfsfunktion zu verwenden, verwendet leider ein Lambda, das für mich nur verdeckt, was es tut. Eine einfachere Funktion mit einem Zweck, der kein Lambda, sondern nur Werte benötigt, ist für mich viel besser.
PS Wenn Sie die ES6-Syntax mögen:
quelle
translateValueIfEqual
den ich für aussagekräftiger hielt, aber ich habe ihn geändert, nachdem jemand dachte, er sei zu lang. Ähnlich wie bei derNz
Funktion in Access wissen Sie es, wenn Sie es wissen, und wenn Sie es nicht wissen, wissen Sie es nicht. In modernen IDEs können Sie einfach eine Taste drücken, um zur Definition zu springen. Und der Fallback wäre die Zwischenvariable. Ich sehe hier keinen großen Nachteil.Ich denke, der
||
Betreiber kann zugeschnitten werden aufindexOf
:Der zurückgegebene Wert wird um 1 nach oben verschoben, was 0 von -1 ergibt, was falsch ist und daher durch die zweite 1 ersetzt wird. Dann wird er zurück verschoben.
Beachten Sie jedoch, dass die Lesbarkeit der Vermeidung von Wiederholungen überlegen ist.
quelle
Dies ist eine einfache Lösung mit bitweisem NICHT und einem Standardwert, der
-1
später zu Null führt.Es funktioniert grundsätzlich mit einem doppelten bitweisen NOT, das den ursprünglichen Wert zurückgibt, oder einem Standardwert, der nach dem Anwenden des bitweisen NOT Null zurückgibt.
Werfen wir einen Blick auf die Tabelle der Wahrheit:
quelle
Sie könnten eine Neuzuweisung verwenden:
&&
Operators für die Neuzuweisung, da der zweite Ausdruck nicht ausgewertet wird, wenn die erste Bedingung falsch istEx.
Code-Snippet anzeigen
quelle
someArray.indexOf
wird nur einmal ausgeführtvalue
.-1
und0
; Andernfallsmax()
wäre das die beste OptionAgain, not seeking an answer to the exact question above
, was die Frage der InterpretationAngesichts des Beispielcodes bei Frage ist nicht klar, wie bestimmt werden würde, ob der
3
Index0
von festgelegt ist oder nichtsomeArray
.-1
Eine Rückgabe von.indexOf()
wäre in diesem Fall wertvoll, um eine vermutete Nichtübereinstimmung auszuschließen, die eine Übereinstimmung sein könnte.Wenn
3
nicht im Array enthalten,-1
wird zurückgegeben. Wir können hinzufügen ,1
um Ergebnis.indexOf()
zu bewertenfalse
für Ergebnis Wesen-1
, wo durch gefolgt||
OR
Betreiber und0
. Wenn daraufvalue
verwiesen wird, subtrahieren Sie1
, um den Index des Elements des Arrays oder zu erhalten-1
.Was dazu führt
.indexOf()
, dass-1
einif
Zustand einfach verwendet und überprüft wird. Oder definiert ,value
wieundefined
zu vermeiden , mögliche Verwirrung in Bezug auf tatsächliches Ergebnis des ausgewerteten Zustandes ursprüngliche Referenz beziehen.quelle
Ein Ternär ist wie ein Wenn-Sonst. Wenn Sie den Sonst-Teil nicht benötigen, warum nicht einfach einen einzigen, wenn stattdessen.
quelle
In diesem speziellen Fall können Sie einen Kurzschluss mit dem logischen
||
Operator verwenden. Als0
falsy betrachtet wird, können Sie hinzufügen ,1
um Ihren Index, wenn alsoindex+1
ist0
dann werden Sie mit der rechten Seite des logischen oder als Ihr Ergebnis erhalten, andernfalls werden Sie Ihre bekommenindex+1
. Da Ihr gewünschtes Ergebnis um versetzt ist1
, können Sie es subtrahieren1
, um Ihren Index zu erhalten:quelle