So schreiben Sie einen ternären Operatorausdruck (auch bekannt als if), ohne sich zu wiederholen

104

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

user1354934
quelle
2
Also ein ifund nicht einif/else
null00ne
53
just an example of when you might have repeated things in the ternaryWiederholen Sie berechnete Ausdrücke nicht. Dafür sind Variablen da.
Vol7ron
4
Wie stellen wir fest, dass dies 3nicht der Index 0von ist someArray?
guest271314
3
Was ist dein Ziel hier? Versuchen Sie, die Zeilenlänge zu reduzieren, oder versuchen Sie speziell, die Wiederholung einer Variablen in einem Ternär zu vermeiden? Ersteres ist möglich, letzteres nicht (zumindest ohne Verwendung von Ternären).
Asgallant
5
Warum nicht Math.max(someArray.indexOf(3), 0)stattdessen verwenden?
301_Moved_Permanent

Antworten:

176

Persönlich finde ich, dass der beste Weg, dies zu tun, immer noch die gute alte ifAussage ist:

var value = someArray.indexOf(3);
if (value === -1) {
  value = 0;
}
Slebetman
quelle
32
Diese Antwort befürwortet die Verwendung einer Variablen zum Speichern eines Zwischenergebnisses und nicht die Verwendung einer ifAnweisung anstelle eines ternären Ergebnisses . Ternäre Anweisungen sind immer noch häufig nützlich, um eine Auswahl als Teil eines Ausdrucks durchzuführen.
Triptychon
4
@ Triptychon: Schau es dir noch einmal an. Es wird überhaupt keine Zwischenvariable verwendet. Stattdessen weist es das Ergebnis direkt der endgültigen Variablen zu und überschreibt es dann, wenn die Bedingung erfüllt ist.
Slebetman
14
Falsch. Der valuenach 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. Erst ifwenn die Aussage abgeschlossen ist, valueenthält sie den richtigen Wert. Das Ternär im OP ist eine bessere Lösung als dies, da es niemals in einen Zwischenzustand übergeht.
Jack Aidley
44
@ JackAidley: "Das Ternär im OP ist eine bessere Lösung als dies, weil es niemals in einen Zwischenzustand übergeht." - Ich werde nicht zustimmen müssen. Dies ist viel besser lesbar als der Code von OP und völlig idiomatisch. Es macht auch einen Fehler in der OP-Logik für mich etwas offensichtlicher (Was passiert nämlich, wenn indexOf () Null zurückgibt? Wie unterscheidet man eine "echte" Null von einer "nicht gefundenen" Null?).
Kevin
2
Dies kommt dem nahe, was ich tun würde, außer dass valuehier technisch mutiert ist, was ich zu vermeiden versuche.
Dave Cousineau
102

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 indexzu verwenden, um die Lesbarkeit zu maximieren ( bei minimalen Laufzeitkosten stelle ich auch fest):

var index = someArray.indexOf( 3 );
var value = index == -1 ? 0 : index;

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 varAnweisung

Sie können die varFähigkeit der Anweisung verwenden, eine zweite temporäre Variable zu definieren (und zuzuweisen), indexwenn sie durch Kommas getrennt wird:

var index = someArray.indexOf(3), value = index !== -1 ? index: 0;

2: Selbstausführende anonyme Funktion

Eine weitere Option ist eine selbstausführende anonyme Funktion:

// Traditional syntax:
var value = function( x ) { return x !== -1 ? x : 0 }( someArray.indexOf(3) );

// ES6 syntax:
var value = ( x => x !== -1 ? x : 0 )( someArray.indexOf(3) );

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 den Kommaoperator verwenden, wenn Sie mehrere Ausdrücke an einer Stelle einfügen möchten, für die ein einzelner Ausdruck erforderlich ist.

Sie können es verwenden, um Nebenwirkungen einzuführen, in diesem Fall indem Sie Folgendes neu zuweisen value:

var value = ( value = someArray.indexOf(3), value !== -1 ? value : 0 );

Dies funktioniert, weil var valuezuerst interpretiert wird (da es sich um eine Anweisung handelt), dann die valueZuordnung 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 valueals Unterausdruck in Klammern verwendet wird:

var value = ( ( value = someArray.indexOf(3) ) !== -1 ? value : 0 );

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 : yzu idx == -1 ? y : x:

var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );
Dai
quelle
97
All dies ist die Art von "cleverer" Codierung, die mich dazu bringen würde, ein paar Sekunden lang darauf zu starren, bevor ich dachte "huh, ich denke, das funktioniert." Sie helfen nicht bei der Klarheit, und da Code mehr gelesen als geschrieben wird, ist dies wichtiger.
Gavin S. Yancey
18
@ g.rocket Ansatz 1 ist zu 100% lesbar und klar und der einzige Weg, wenn Sie Wiederholungen vermeiden möchten (das kann sehr schädlich sein, wenn Sie eine komplexe und problematische Funktion anstelle einer einfachen indefOf
aufrufen
5
Einverstanden ist # 1 sehr gut lesbar und wartbar, die anderen beiden nicht so sehr.
verzeihen,
6
Ich glaube, Sie können für # 3 vereinfachen, var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);anstatt ein Komma zu verwenden.
IllusiveBrian
2
Im zweiten Beispiel Selbstausführende anonyme Funktion können Sie Klammern in der Pfeilfunktion weglassen. var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );weil ist nur ein Parameter.
Alex Char
54

Für Zahlen

Sie können die Math.max()Funktion verwenden.

var value = Math.max( someArray.indexOf('y'), 0 );

Dadurch bleiben die Grenzen des Ergebnisses 0bis zum ersten Ergebnis größer als in 0diesem Fall. Und wenn das Ergebnis von indexOfist -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 ( ||):

// Instead of
var variable = this_one === true ? this_one : or_this_one;
// you can use
var variable = this_one || or_this_one;

Sie müssen damit sehr vorsichtig sein, da in Ihrem ersten Beispiel zurückgegeben werden indexOfkann 0und wenn Sie bewerten 0 || -1, wird es zurückgegeben, -1weil 0es sich um einen falschen Wert handelt.

Crisoforo Gaspar
quelle
2
Vielen Dank. Ich denke mein Beispiel ist schlecht. Ich gebe nur ein allgemeines Beispiel, haha, ich suche keine Lösung für die genaue Frage. Ich habe einige Szenarien wie das Beispiel gesehen, in dem ich ein ternäres verwenden möchte, aber am Ende wiederhole :(
user1354934
1
Wie stellen wir im ersten Beispiel fest, ob der Index von ist 3oder "y"nicht ? 0someArray
guest271314
Am Math.maxBeispiel? indexOfGibt 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.maxSetzen Sie dann einfach die Grenzen von 0 bis zur Länge, um die Chance zu beseitigen ein -1,
Crisoforo Gaspar
@mitogh Die Logik bei Code bei OP erzeugt ein Problem, obwohl es ein allgemeines Beispiel ist. wobei 0 beide den Index 0des übereinstimmenden Elements innerhalb des Arrays anzeigen oder auf 0setzen könnte Math.max(); oder beim bedingten Bediener bei OP. Überlegen Sie var value = Math.max( ["y"].indexOf("y"), 0 ). Wie bestimmen Sie, welche 0zurückgegeben wird? 0an den Math.max()Aufruf übergeben oder den 0Index "y"innerhalb des Arrays widerspiegeln ?
guest271314
@ guest271314 Guter Gedanke, aber ich denke, es hängt vom Kontext ab, ob das ein Problem ist oder nicht. Vielleicht spielt es keine Rolle, woher die 0 kam, und das einzig Wichtige ist, dass es nicht -1 ist. Ein Beispiel: Möglicherweise müssen Sie ein Element aus einem Array auswählen. Sie möchten ein bestimmtes Element (im OP die Nummer 3), aber wenn es nicht im Array enthalten ist, benötigen Sie immer noch ein Element, und Sie können standardmäßig das erste Element verwenden, vorausgesetzt, Sie wissen, dass das Array nicht vorhanden ist. t leer.
Kev
27

Nicht wirklich, verwenden Sie einfach eine andere Variable.

Ihr Beispiel verallgemeinert sich auf so etwas.

var x = predicate(f()) ? f() : default;

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.

var computed = f();
var x = predicate(computed) ? computed : default;

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:

var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)
Triptychon
quelle
17

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 aauf BooleanRückkehr false, resultwird zugewiesen 'fallback value', andernfalls den Wert a.


Achten Sie auf den Randfall a === 0, der (falsch) geworfen wird falseund resultwird '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';

Lyubomir
quelle
3
PHP (> 7.0) und C # unterstützen auch den Null-Koaleszenz-Operator. Syntaktischer Zucker, aber sicherlich sehr schön.
Hissvard
5
Dies funktioniert nur, wenn die Funktion bei einem Fehler einen Falsey-Wert zurückgibt indexOf(), in diesem Muster jedoch nicht verwendet werden kann.
Barmar
1
Richtig, aber er fragt nicht nach dem konkreten Beispiel Ersetzen Sie das sich wiederholende Ternär (Ergebnis = a? a: b). Und das Wiederholen von ternär ist gleichbedeutend mit || (Ergebnis = a || b)
Lyubomir
2
Ist das wirklich wie ||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.
Loduwijk
1
Beachten Sie auch, dass die Frage den Wert mit vergleicht -1. Auch hier kann ich nicht für JavaScript und seine Macken sprechen, aber im Allgemeinen -1wä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.
Loduwijk
8

Verwenden Sie ein Refactoring für Extraktvariablen :

var index = someArray.indexOf(3);
var value = index !== -1 ? index : 0

Es ist noch besser mit conststatt var. Sie können auch eine zusätzliche Extraktion durchführen:

const index = someArray.indexOf(3);
const condition = index !== -1;
const value = condition ? index : 0;

In der Praxis verwendet aussagekräftigeren Namen als index, conditionund value.

const threesIndex = someArray.indexOf(3);
const threeFound = threesIndex !== -1;
const threesIndexOrZero = threeFound ? threesIndex : 0;
Dave Cousineau
quelle
Was ist eine "Extraktvariable"? Ist das ein etablierter Begriff?
Peter Mortensen
6

Sie suchen wahrscheinlich nach einem Koaleszenzoperator. Glücklicherweise können wir den ArrayPrototyp nutzen, um einen zu erstellen:

Array.prototype.coalesce = function() {
    for (var i = 0; i < this.length; i++) {
        if (this[i] != false && this[i] != null) return this[i];
    }
}

[null, false, 0, 5, 'test'].coalesce(); // returns 5

Dies könnte durch Hinzufügen eines Parameters zur Funktion weiter auf Ihren Fall verallgemeinert werden:

Array.prototype.coalesce = function(valid) {
    if (typeof valid !== 'function') {
        valid = function(a) {
            return a != false && a != null;
        }
    }

    for (var i = 0; i < this.length; i++) {
        if (valid(this[i])) return this[i];
    }
}

[null, false, 0, 5, 'test'].coalesce(); // still returns 5
[null, false, 0, 5, 'test'].coalesce(function(a){return a !== -1}); // returns null
[null, false, 0, 5, 'test'].coalesce(function(a){return a != null}); //returns false
Tyzoid
quelle
Das Hinzufügen zum Prototyp von Arrays ist riskant, da das neue Element in jedem Array zu einem Index wird. Dies bedeutet , dass durch den Indizes Iterieren auch das neue Verfahren umfasst: for (let x in ['b','c']) console.log(x);druckt 0, 1, "coalesce".
Charlie Harding
@CharlieHarding True, aber es wird im Allgemeinen nicht empfohlen, den for-in-Operator zu verwenden, wenn Sie Arrays durchlaufen. Siehe stackoverflow.com/a/4374244/1486100
Tyzoid
6

Ich persönlich bevorzuge zwei Varianten:

  1. Rein wenn, wie @slebetman vorgeschlagen hat

  2. Separate Funktion, die einen ungültigen Wert durch einen Standardwert ersetzt, wie in diesem Beispiel:

function maskNegative(v, def) {
  return v >= 0 ? v : def;
}

Array.prototype.indexOfOrDefault = function(v, def) {
  return maskNegative(this.indexOf(v), def);
}

var someArray = [1, 2];
console.log(someArray.indexOfOrDefault(2, 0)); // index is 1
console.log(someArray.indexOfOrDefault(3, 0)); // default 0 returned
console.log(someArray.indexOfOrDefault(3, 123)); // default 123 returned

Iłya Bursov
quelle
1
+1, Option 2 respektiert die Inline-Absicht der Frage, kann effizient auf andere Sprachen als Javascript angewendet werden und fördert die Modularität.
Devsman
5

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:

function get_value(arr) {
   var value = arr.indexOf(3);
   if (value === -1) {
     value = 0;
   }
   return value;
}

Dann ruf einfach an

var value = get_value( someArray );

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.

Adam
quelle
4

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):

var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0;

kann (und sollte angesichts der Funktionsaufrufe) wie folgt gekürzt werden:

var value = someArray.indexOf(3);
value = value !== -1 ? value : 0;

Wenn Sie nach einer allgemeineren Lösung suchen, die die Wiederholung einer Variablen in einem Ternär verhindert, wie folgt:

var value = conditionalTest(foo) ? foo : bar;

wo foonur einmal erscheint. Lösungen der Form verwerfen:

var cad = foo;
var value = conditionalTest(foo) ? cad : bar;

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 ist falsey:

var value = foo || bar; // equivalent to !foo ? bar : foo
asgallant
quelle
1
Die Frage ist mit Javascript gekennzeichnet und erwähnt C # nicht. Ich frage mich nur, warum Sie mit C # -spezifischen Beispielen enden.
Loduwijk
Ich habe das Javascript-Tag für die Frage verpasst. entfernte das C #.
Asgallant
3

Verwenden Sie eine Hilfsfunktion:

function translateValue(value, match, translated) {
   return value === match ? translated : value;
}

Jetzt ist Ihr Code sehr gut lesbar und es gibt keine Wiederholung.

var value = translateValue(someArray.indexOf(3), -1, 0);

Die Hierarchie der Codierungsprobleme lautet:

  1. Richtig (einschließlich wahrer Leistung oder SLA-Bedenken)
  2. klar
  3. Prägnant
  4. Schnell

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:

const translateValue = (value, match, translated) => value === match ? translated : value;
let value = translateValue(someArray.indexOf(3), -1, 0); // or const
ErikE
quelle
2
"Meine Version hat die höchste Klarheit" - ich bin anderer Meinung. Der Funktionsname ist viel zu lang und die Eingabe und Ausgabe von Benennungsparametern ist überhaupt nicht hilfreich.
Adelphus
Können Sie also bessere Namen vorschlagen? Ich würde sie gerne unterhalten. Ihre Beschwerde bezieht sich ausschließlich auf Kosmetika. Lassen Sie uns also die Kosmetik reparieren. Richtig? Ansonsten bist du nur Fahrradschuppen.
ErikE
In einigen Fällen kann eine solche Hilfsfunktion nützlich sein. In diesem Fall, in dem nur ein bestimmter Fall eines ternären Operators ersetzt wird, ist Ihre Funktion weniger klar. Ich werde mich nicht daran erinnern, was Ihre Funktion tut, und ich muss sie jedes Mal nachschlagen, wenn ich darauf stoße, und ich würde mich nie daran erinnern, sie zu verwenden.
Loduwijk
1
@ Aaron Das ist eine vernünftige Einschätzung für einen bestimmten Anwendungsfall. Für das, was es wert ist, war mein ursprünglicher Funktionsname, translateValueIfEqualden ich für aussagekräftiger hielt, aber ich habe ihn geändert, nachdem jemand dachte, er sei zu lang. Ähnlich wie bei der NzFunktion 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.
ErikE
1
Dies zeigt nur, dass Sie 10 verschiedene Antworten erhalten, wenn Sie 5 verschiedenen Ingenieuren dieselbe Frage stellen.
Loduwijk
2

Ich denke, der ||Betreiber kann zugeschnitten werden auf indexOf:

var value = ((someArray.indexOf(3) + 1) || 1) - 1;

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.

IllidanS4 will Monica zurück
quelle
2

Dies ist eine einfache Lösung mit bitweisem NICHT und einem Standardwert, der -1später zu Null führt.

index = ~(~array.indexOf(3) || -1);

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:

 indexOf    ~indexOf   boolean    default     value      result         comment
---------  ---------  ---------  ---------  ---------  ---------  ------------------
      -1          0     falsy          -1         -1          0   take default value
       0         -1    truthy                     -1          0
       1         -2    truthy                     -2          1
       2         -3    truthy                     -3          2
Nina Scholz
quelle
0

Sie könnten eine Neuzuweisung verwenden:

  • Variable auf einen Wert initialisieren
  • Verwenden Sie die Serialisierung des &&Operators für die Neuzuweisung, da der zweite Ausdruck nicht ausgewertet wird, wenn die erste Bedingung falsch ist

Ex.

var value = someArray.indexOf(3);
value == -1 && (value=0);

vol7ron
quelle
3
@MinusFour Bis zu einem gewissen Grad. Die Variable wird wiederholt, nicht der Ausdruck someArray.indexOfwird nur einmal ausgeführt
vol7ron
Du wiederholst value.
MinusFour
3
@MinusFour Richtig, aber dies ist für größere Ausdrücke nützlicher. Das Wiederholen einer Variablen ist im Vergleich zum Speichern der Operationen unbedeutend. Ich vermute, das OP arbeitet nicht mit -1und 0; Andernfalls max()wäre das die beste Option
Vol7ron
2
Richtig ... aber die Frage ist ... "Wie man Ternäre schreibt, ohne sich zu wiederholen "
MinusFour
4
Es heißt auch Again, not seeking an answer to the exact question above, was die Frage der Interpretation
überlässt
0

Angesichts des Beispielcodes bei Frage ist nicht klar, wie bestimmt werden würde, ob der 3Index 0von festgelegt ist oder nicht someArray. -1Eine Rückgabe von .indexOf()wäre in diesem Fall wertvoll, um eine vermutete Nichtübereinstimmung auszuschließen, die eine Übereinstimmung sein könnte.

Wenn 3nicht im Array enthalten, -1wird zurückgegeben. Wir können hinzufügen , 1um Ergebnis .indexOf()zu bewerten falsefür Ergebnis Wesen -1, wo durch gefolgt || ORBetreiber und 0. Wenn darauf valueverwiesen wird, subtrahieren Sie 1, um den Index des Elements des Arrays oder zu erhalten -1.

Was dazu führt .indexOf(), dass -1ein ifZustand einfach verwendet und überprüft wird. Oder definiert , valuewie undefinedzu vermeiden , mögliche Verwirrung in Bezug auf tatsächliches Ergebnis des ausgewerteten Zustandes ursprüngliche Referenz beziehen.

var someArray = [1,2,3];
var value = someArray.indexOf(3) + 1 || 1;
console.log(value -= 1);

var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || 1;
// how do we know that `4` is not at index `0`?
console.log(value -= 1);

var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || void 0;
// we know for certain that `4` is not found in `someArray`
console.log(value, value = value || 0);

guest271314
quelle
0

Ein Ternär ist wie ein Wenn-Sonst. Wenn Sie den Sonst-Teil nicht benötigen, warum nicht einfach einen einzigen, wenn stattdessen.

if ((value = someArray.indexOf(3)) < 0) value = 0;
Khaled.K
quelle
0

In diesem speziellen Fall können Sie einen Kurzschluss mit dem logischen ||Operator verwenden. Als 0falsy betrachtet wird, können Sie hinzufügen , 1um Ihren Index, wenn also index+1ist 0dann werden Sie mit der rechten Seite des logischen oder als Ihr Ergebnis erhalten, andernfalls werden Sie Ihre bekommen index+1. Da Ihr gewünschtes Ergebnis um versetzt ist 1, können Sie es subtrahieren 1, um Ihren Index zu erhalten:

const someArray = [1, 2, 3, 4];
const v = ((someArray.indexOf(3)+1) || 1)-1;
console.log(v);

Nick Parsons
quelle