Jak napisać operator trójskładnikowy (aka if) bez powtarzania siebie

104

Na przykład coś takiego:

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

Czy jest lepszy sposób, aby to napisać? Ponownie, nie szukam odpowiedzi na dokładne pytanie powyżej, tylko przykład tego, kiedy możesz mieć powtarzające się operandy w wyrażeniach operatorów trójskładnikowych ...

user1354934
źródło
2
Więc an ifi nieif/else
zer00ne
53
just an example of when you might have repeated things in the ternarynie powtarzaj obliczonych wyrażeń. Do tego służą zmienne.
vol7ron
4
W jaki sposób możemy stwierdzić, że 3nie ma w indeksie 0z someArray?
gość271314
3
Jaki jest twój cel? Czy próbujesz zmniejszyć długość linii, czy konkretnie próbujesz uniknąć powtórzenia zmiennej w trójskładniku? Pierwsza jest możliwa, druga nie (przynajmniej nie używa trójskładników).
asgallant
5
Dlaczego nie użyć Math.max(someArray.indexOf(3), 0)zamiast tego?
301_Moved_Permanently Kwietnia

Odpowiedzi:

176

Osobiście uważam, że najlepszym sposobem, aby to zrobić, jest wciąż stare dobre ifstwierdzenie:

var value = someArray.indexOf(3);
if (value === -1) {
  value = 0;
}
slebetman
źródło
32
Aby było jasne, w tej odpowiedzi zaleca się użycie zmiennej do przechowywania wyniku pośredniego, a nie użycie ifinstrukcji zamiast trójskładnika. Instrukcje trójskładnikowe są nadal często przydatne do dokonywania wyboru jako części wyrażenia.
Tryptyk
4
@Triptych: Spójrz na to jeszcze raz. W ogóle nie używa zmiennej pośredniej. Zamiast tego przypisuje wynik bezpośrednio do końcowej zmiennej, a następnie zastępuje ją, jeśli warunek jest spełniony.
slebetman
14
Błędny. Wartość przechowywana valueza pierwszym wierszem jest pośrednia. Nie zawiera prawidłowej wartości, która jest następnie ustalana w następnym wierszu, a zatem jest wartością pośrednią. Dopiero po ifstwierdzeniu, że instrukcja valuezawiera prawidłową wartość. Trójskładnik w PO jest lepszym rozwiązaniem niż to, ponieważ nigdy nie wchodzi w stan pośredni.
Jack Aidley,
44
@JackAidley: „Trójskładnik w OP jest lepszym rozwiązaniem, ponieważ nigdy nie wchodzi w stan pośredni”. - Będę musiał się nie zgodzić. Jest to o wiele bardziej czytelne niż kod OP i całkowicie idiomatyczne. Sprawia to również, że błąd w logice OP jest dla mnie nieco bardziej oczywisty (Mianowicie, co się stanie, jeśli indexOf () zwróci zero? Jak odróżnić „prawdziwe” zero od „nie znalezionego” zera?).
Kevin
2
jest to bliskie temu, co bym zrobił, z wyjątkiem tego, że valuetutaj jest technicznie zmutowany, którego staram się uniknąć.
Dave Cousineau
102

Kod powinien być czytelny, więc bycie zwięzłym nie powinno oznaczać zwięzłości bez względu na koszty - w tym celu prześlij ponownie na https://codegolf.stackexchange.com/ - więc zamiast tego zalecałbym użycie drugiej zmiennej lokalnej o nazwie, indexaby zmaksymalizować czytelność tekstu ( przy minimalnych kosztach czasu działania, zauważam):

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

Ale jeśli naprawdę chcesz uciąć to wyrażenie, ponieważ jesteś okrutnym sadystą dla swoich współpracowników lub współpracowników projektu, oto 4 podejścia, których możesz użyć:

1: Zmienna tymczasowa w varinstrukcji

Możesz użyć varzdolności instrukcji do zdefiniowania (i przypisania) drugiej zmiennej tymczasowej index, oddzielonej przecinkami:

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

2: Samowykonująca się funkcja anonimowa

Inną opcją jest samowykonująca się anonimowa funkcja:

// 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: Operator przecinka

Istnieje również niesławny „operator przecinka” obsługiwany przez JavaScript, który jest również obecny w C i C ++.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

Możesz użyć operatora przecinka, jeśli chcesz dołączyć wiele wyrażeń w lokalizacji, która wymaga jednego wyrażenia.

Możesz go użyć do wprowadzenia efektów ubocznych, w tym przypadku ponownie przypisując do value:

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

To działa, ponieważ var valuejest najpierw interpretowane (ponieważ jest to instrukcja), a następnievalue przypisanie skrajne lewe, najbardziej wewnętrzne , a następnie prawa ręka operatora przecinka, a następnie operator trójskładnikowy - cały legalny JavaScript.

4: Przypisz ponownie w podwyrażeniu

Komentator @IllusiveBrian zwrócił uwagę, że użycie operatora przecinka (w poprzednim przykładzie) jest niepotrzebne, jeśli przypisanie do valuejest używane jako podwyrażenie w nawiasach:

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

Zauważ, że używanie negatywów w wyrażeniach logicznych może być trudniejsze do naśladowania dla ludzi - dlatego wszystkie powyższe przykłady można uprościć do czytania, zmieniając idx !== -1 ? x : yna idx == -1 ? y : x:

var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );
Dai
źródło
97
To wszystko jest rodzajem „sprytnego” kodowania, przez które wpatruję się w niego przez kilka sekund, zanim pomyślałem „huh, myślę, że to działa”. Nie pomagają one w zrozumieniu, a ponieważ kod jest czytany więcej niż jest napisany, jest to ważniejsze.
Gavin S. Yancey
18
@ g. podejście rakietowe 1 jest w 100% czytelne i przejrzyste, a jedyny sposób, aby to zrobić, jeśli chcesz uniknąć powtórzeń (może to być naprawdę szkodliwe, jeśli wywołujesz jakąś złożoną i problematyczną funkcję zamiast prostej indefOf)
edc65
5
Zgoda, numer 1 jest bardzo czytelny i łatwy w utrzymaniu, pozostałe dwa nie są tak bardzo.
wybaczenie
6
W przypadku # 3 uważam, że można uprościć do var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);zamiast używać przecinka.
IllusiveBrian
2
W drugim przykładzie Samowykonująca się funkcja anonimowa może pominąć nawiasy w funkcji strzałkowej. var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );ponieważ jest tylko jednym parametrem.
Alex Char
54

Dla liczb

Możesz użyć Math.max()funkcji.

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

Zachowa granice wyniku od 0aż do pierwszego wyniku większe niż 0w takim przypadku. I jeśli wynik ze indexOfjest -1to zwróci 0, jak jest większa niż -1.

Dla wartości logicznych i logicznych-y

W przypadku JS nie ma ogólnej reguły AFAIK, szczególnie ze względu na sposób oceny fałszywych wartości.

Ale jeśli coś może ci pomóc przez większość czasu, to operator lub ( ||):

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

Musisz być z tym bardzo ostrożny, ponieważ w pierwszym przykładzie indexOfmoże powrócić 0i jeśli oszacujesz 0 || -1, zwróci, -1ponieważ 0jest fałszywą wartością.

Crisoforo Gaspar
źródło
2
Dzięki. Myślę, że mój przykład jest zły, podaję tylko ogólny przykład, haha, nie szukam rozwiązania konkretnego pytania. Spotkałem kilka scnarios, takich jak przykład, w którym chciałbym użyć trójskładnika, ale w końcu się powtarzam :(
user1354934
1
W pierwszym przykładzie, w jaki sposób ustalić, 3czy "y"nie ma w indeksie 0z someArray?
gość271314
Na Math.maxprzykładzie? indexOfzwraca indeks elementu, a jeśli element nie zostanie znaleziony, zwraca -1, więc masz szanse na uzyskanie liczby od -1 do długości łańcucha, a następnie Math.maxustaw granice od 0 do długości, aby usunąć szansę aby zwrócić -1,
Crisoforo Gaspar
@mitogh Logika kodu w OP tworzy problem, chociaż jest to ogólny przykład; gdzie 0 może jednocześnie wskazywać indeks 0dopasowanego elementu w tablicy lub 0ustawić na Math.max(); lub u operatora warunkowego w OP. Rozważ var value = Math.max( ["y"].indexOf("y"), 0 ). Jak ustalasz, który produkt 0jest zwracany? 0przekazane do Math.max()wywołania lub 0odzwierciedlające indeks "y"wewnątrz tablicy?
gość271314
@ guest271314 Dobra myśl, ale myślę, że zależy to od kontekstu, czy to jest problem, czy nie. Być może nie ma znaczenia, skąd pochodzi 0, a jedyną ważną rzeczą jest to, że nie jest to -1. Przykład: być może musisz wybrać element z tablicy. Chcesz określonego elementu (w OP, numer 3), ale jeśli nie ma go w tablicy, nadal potrzebujesz elementu i możesz ustawić domyślne ustawienie na pierwszy element, zakładając, że wiesz, że tablica nie jest t pusty.
Kev
27

Niezupełnie, po prostu użyj innej zmiennej.

Twój przykład uogólnia coś takiego.

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

Testujesz obliczoną wartość, a następnie przypisujesz ją do zmiennej, jeśli przekazuje ona jakiś predykat. Sposób uniknięcia ponownego obliczania obliczonej wartości jest oczywisty: użyj zmiennej do przechowywania wyniku.

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

Rozumiem, co masz na myśli - wygląda na to, że powinien być jakiś sposób na zrobienie tego, który będzie wyglądał na trochę czystszy. Ale myślę, że to najlepszy sposób (idiomatycznie), aby to zrobić. Jeśli z jakiegoś powodu często powtarzałeś ten wzorzec w swoim kodzie, możesz napisać małą funkcję pomocniczą:

var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)
Tryptyk
źródło
17

EDYCJA: Oto propozycja koalescencji zerowej teraz w JavaScript!


Posługiwać się ||

const result = a ? a : 'fallback value';

jest równa

const result = a || 'fallback value';

Jeśli rzutowanie ana Booleanzwraca false, resultzostanie przypisana 'fallback value', w przeciwnym razie wartość a.


Uważaj na przypadek krawędzi a === 0, który rzuca falsei result(nieprawidłowo) przyjmie 'fallback value'. Używaj takich sztuczek na własne ryzyko.


PS. Języki takie jak Swift mają operator koalescencji nil ( ??), który służy podobnemu celowi. Na przykład w Swift można napisać, result = a ?? "fallback value"który jest bardzo zbliżony do JavaScriptconst result = a || 'fallback value';

Lyubomir
źródło
3
PHP (> 7.0) i C # również obsługują operator łączenia wartości null. Cukier syntaktyczny, ale z pewnością cudowny.
Hissvard
5
Działa to tylko wtedy, gdy funkcja zwraca wartość falsey, gdy się nie powiedzie, ale indexOf()nie można jej użyć w tym wzorcu.
Barmar
1
Zgadza się, ale nie pyta o konkretny przykład> „Znowu, nie szukając odpowiedzi na powyższe pytanie, tylko przykład tego, kiedy mogłeś powtórzyć pewne rzeczy w trójek” <, pamiętaj, że raczej prosi o ogólny sposób zamień powtarzający się potrójny (wynik = a? a: b). Powtarzanie trójskładnika jest równoważne z || (wynik = a || b)
Lyubomir
2
Czy to naprawdę jak ||działa w JavaScript? Jeśli dobrze cię rozumiem, to działa inaczej niż wiele innych języków podstawowych (myślę przede wszystkim o C i jego potomkach [C ++, Java itp.]). Nawet jeśli tak naprawdę ||działa w JavaScript, odradzałbym używanie sztuczki takie jak ta, które wymagają od opiekunów znajomości specjalnych dziwactw dotyczących języka. Chociaż ta sztuczka jest fajna, uznałbym ją za złą praktykę.
Loduwijk
1
Zauważ również, że pytanie dotyczy porównania wartości z -1. Ponownie, nie mogę mówić o JavaScript i jego dziwactwach, ale generalnie -1byłaby to wartość prawdziwa, a nie fałszywa, a zatem twoja odpowiedź nie zadziałałaby w przypadku pytania, a na pewno nie w ogólnym przypadku, raczej działałaby tylko w określonym ( ale dość powszechne) przypadek podrzędny.
Loduwijk
8

Użyj wyodrębnionej zmiennej refaktoryzacji :

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

Jest jeszcze lepiej z constzamiast var. Możesz także wykonać dodatkową ekstrakcję:

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

W praktyce użyć więcej niż znaczące nazwy index, conditioni value.

const threesIndex = someArray.indexOf(3);
const threeFound = threesIndex !== -1;
const threesIndexOrZero = threeFound ? threesIndex : 0;
Dave Cousineau
źródło
Co to jest „zmienna wyodrębniana”? Czy to ustalony termin?
Peter Mortensen
6

Prawdopodobnie szukasz operatora koalescencji. Na szczęście możemy wykorzystać Arrayprototyp do stworzenia jednego:

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

Można to dodatkowo uogólnić w Twoim przypadku, dodając parametr do funkcji:

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
źródło
Dodawanie do prototypu tablic jest ryzykowne, ponieważ nowy element staje się indeksem wewnątrz każdej tablicy. Oznacza to, że iteracja indeksów obejmuje również nową metodę: for (let x in ['b','c']) console.log(x);drukuje 0, 1, "coalesce".
Charlie Harding
@CharlieHarding True, ale generalnie nie zaleca się używania operatora for-in podczas przeglądania tablic w pętli. Zobacz stackoverflow.com/a/4374244/1486100
Tyzoid
6

Osobiście wolę dwa warianty:

  1. Czyste, jeśli, jak sugerował @slebetman

  2. Oddzielna funkcja, która zamienia nieprawidłową wartość na domyślną, jak w tym przykładzie:

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
źródło
1
+1, opcja 2 szanuje intencję pytania, może skutecznie stosować się do języków innych niż javascript i promuje modułowość.
Devsman,
5

Podoba mi się odpowiedź @ slebetman. Komentarz pod nim wyraża zaniepokojenie, że zmienna znajduje się w „stanie pośrednim”. jeśli jest to dla Ciebie duży problem, sugeruję zamknięcie go w funkcji:

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

Po prostu zadzwoń

var value = get_value( someArray );

Możesz zrobić bardziej ogólne funkcje, jeśli masz ich zastosowania w innych miejscach, ale nie przesadzaj, jeśli jest to bardzo specyficzny przypadek.

Ale szczerze mówiąc, zrobiłbym po prostu jako @slebetman, chyba że musiałbym ponownie użyć z kilku miejsc.

Adam
źródło
4

Są dwa sposoby, w jakie mogę spojrzeć na twoje pytanie: albo chcesz zmniejszyć długość linii, albo specjalnie chcesz uniknąć powtarzania zmiennej w trójskładniku. Pierwsza jest trywialna (i wielu innych użytkowników zamieściło przykłady):

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

można (i powinno się, biorąc pod uwagę wywołania funkcji) skrócić w następujący sposób:

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

Jeśli szukasz bardziej ogólnego rozwiązania, które zapobiega powtarzaniu się zmiennej w trójskładniku, na przykład:

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

gdzie foopojawia się tylko raz. Odrzucenie rozwiązań formularza:

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

jako technicznie poprawne, ale nie ma sensu, to nie masz szczęścia. Istnieją operatory, funkcje i metody, które mają zwięzłą składnię, której szukasz, ale takie konstrukcje z definicji nie są operatorami trójskładnikowymi .

Przykłady:

javascript, używając ||do zwrócenia RHS, gdy LHS to falsey:

var value = foo || bar; // equivalent to !foo ? bar : foo
asgallant
źródło
1
Pytanie jest otagowane javascript i nie wspomina o C #. Zastanawiam się tylko, dlaczego kończysz na przykładach specyficznych dla języka C #.
Loduwijk
Brakowało mi znacznika javascript w pytaniu; usunięto C #.
asgallant
3

Użyj funkcji pomocniczej:

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

Teraz twój kod jest bardzo czytelny i nie ma powtórzeń.

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

Hierarchia problemów związanych z kodowaniem jest następująca:

  1. Prawidłowe (w tym rzeczywiste problemy z wydajnością lub SLA)
  2. Jasny
  3. Zwięzły
  4. Szybki

Wszystkie dotychczasowe odpowiedzi na stronie wydają się poprawne, ale myślę, że moja wersja jest najbardziej przejrzysta, co jest ważniejsze niż zwięzłość. Jeśli nie policzysz funkcji pomocniczej - ponieważ można jej użyć ponownie - jest ona również najbardziej zwięzła. Nieco podobna sugestia użycia funkcji pomocniczej niestety wykorzystuje lambdę, która według mnie tylko przesłania to, co robi. Prostsza funkcja z jednym celem, która nie przyjmuje wartości lambda, a tylko wartości, jest dla mnie znacznie lepsza.

PS Jeśli lubisz składnię ES6:

const translateValue = (value, match, translated) => value === match ? translated : value;
let value = translateValue(someArray.indexOf(3), -1, 0); // or const
ErikE
źródło
2
„moja wersja ma najwyższą przejrzystość” - nie zgadzam się. Nazwa funkcji jest zdecydowanie za długa, a nazywanie parametrów wejściowych i wyjściowych nie jest w ogóle pomocne.
adelphus
Czy możesz więc zaproponować lepsze nazwy? Byłbym szczęśliwy, mogąc ich zabawić. Twoja skarga dotyczy wyłącznie kosmetyków, więc naprawmy kosmetyki. Dobrze? W przeciwnym razie po prostu zrzucasz rower.
ErikE
W niektórych przypadkach taka funkcja pomocnicza może być przydatna. W takim przypadku, gdy zastępuje tylko określony przypadek operatora trójskładnikowego, twoja funkcja będzie mniej jasna. Nie będę pamiętał, co robi twoja funkcja, i będę musiał ją sprawdzać za każdym razem, gdy ją napotkam, i nigdy nie pamiętałbym jej użyć.
Loduwijk
1
@Aaron To rozsądna ocena dla konkretnego przypadku użycia. Co więcej, moja pierwotna nazwa funkcji była, jak translateValueIfEqualsądziłem, bardziej opisowa, ale zmieniłem ją po tym, jak ktoś pomyślał, że jest za długa. Podobnie jak Nzfunkcja w programie Access, jeśli ją znasz, znasz ją, a jeśli nie, to nie. W nowoczesnych IDE wystarczy nacisnąć klawisz, aby przejść do definicji. A rezerwą byłaby zmienna pośrednia. Naprawdę nie widzę tutaj dużych wad.
ErikE
1
Pokazuje to, że jeśli zadasz to samo pytanie 5 różnym inżynierom, otrzymasz 10 różnych odpowiedzi.
Loduwijk
2

Myślę, że ||operator można dostosować do indexOf:

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

Zwracana wartość jest przesuwana w górę o 1, co daje 0 z -1, co jest błędem i dlatego jest zastępowane przez drugą 1. Następnie jest cofana.

Należy jednak pamiętać, że czytelność jest lepsza niż unikanie powtórzeń.

IllidanS4 chce powrotu Moniki
źródło
2

Jest to proste rozwiązanie z bitowym NIE i wartością domyślną, -1która jest późniejsza do zera.

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

Działa w zasadzie z podwójnym bitowym NIE, które zwraca oryginalną wartość lub wartość domyślną, która po zastosowaniu bitowego NIE zwraca zero.

Spójrzmy na tabelę prawdy:

 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
źródło
0

Możesz użyć ponownego przypisania:

  • zainicjuj zmienną do jednej wartości
  • użyj serializacji &&operatora do ponownego przypisania, ponieważ jeśli pierwszy warunek jest fałszywy, drugie wyrażenie nie zostanie ocenione

Dawny.

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

vol7ron
źródło
3
@MinusFour Do pewnego stopnia. Zmienna jest powtarzana, a nie wyrażenie someArray.indexOfjest wykonywane tylko raz
vol7ron
Powtarzasz value.
MinusFour
3
@MinusFour Poprawnie, ale jest to bardziej przydatne w przypadku większych wyrażeń, powtarzanie zmiennej jest nieistotne w porównaniu z zapisywaniem operacji. Domyślam się, że OP nie działa z -1i 0; inaczej max()byłaby najlepsza opcja
vol7ron
2
Racja… ale pytanie brzmi… „Jak pisać trójki bez powtarzania siebie”
MinusFour
4
Mówi też Again, not seeking an answer to the exact question above, co pozostawia pytanie interpretacji;)
vol7ron
0

Biorąc pod uwagę przykładowy kod w pytaniu nie jest jasne, w jaki sposób zostać stwierdzone, że 3jest lub nie jest ustawiony na indeks 0z someArray. -1zwrócona z .indexOf()będzie wartościowa w tym przypadku, w celu wykluczenia domniemanego niezgodności, która może być zgodna.

Jeśli 3nie jest uwzględnione w tablicy, -1zostanie zwrócone. Możemy dodać 1do wyniku of, .indexOf()aby oszacować, że falsewynik jest -1, gdzie następuje || ORoperator i 0. Kiedy valuewystępuje odwołanie, odejmij, 1aby uzyskać indeks elementu tablicy lub -1.

Która prowadzi z powrotem po prostu używając .indexOf()i sprawdzanie -1pod ifwarunkiem. Lub zdefiniowanie valuew undefinedcelu uniknięcia możliwego pomyłki co do rzeczywistego wyniku ocenianego stanu w odniesieniu do pierwotnego odniesienia.

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

gość271314
źródło
0

Trójskładnik jest jak if-else, jeśli nie potrzebujesz części else, dlaczego nie tylko pojedynczej, jeśli zamiast ..

if ((value = someArray.indexOf(3)) < 0) value = 0;
Khaled.K
źródło
0

W tym konkretnym przypadku możesz użyć zwarcia z ||operatorem logicznym . Ponieważ 0jest to uważane za fałszywe, możesz dodać 1do swojego indeksu, więc jeśli index+1tak 0, otrzymasz prawą stronę logiki - lub jako wynik, w przeciwnym razie otrzymasz swój index+1. Ponieważ pożądany wynik jest równoważony 1, możesz odjąć 1od niego, aby uzyskać indeks:

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

Nick Parsons
źródło