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 ...
javascript
conditional-operator
user1354934
źródło
źródło
if
i nieif/else
just an example of when you might have repeated things in the ternary
nie powtarzaj obliczonych wyrażeń. Do tego służą zmienne.3
nie ma w indeksie0
zsomeArray
?Math.max(someArray.indexOf(3), 0)
zamiast tego?Odpowiedzi:
Osobiście uważam, że najlepszym sposobem, aby to zrobić, jest wciąż stare dobre
if
stwierdzenie:źródło
if
instrukcji zamiast trójskładnika. Instrukcje trójskładnikowe są nadal często przydatne do dokonywania wyboru jako części wyrażenia.value
za 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 poif
stwierdzeniu, że instrukcjavalue
zawiera prawidłową wartość. Trójskładnik w PO jest lepszym rozwiązaniem niż to, ponieważ nigdy nie wchodzi w stan pośredni.value
tutaj jest technicznie zmutowany, którego staram się uniknąć.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,
index
aby zmaksymalizować czytelność tekstu ( przy minimalnych kosztach czasu działania, zauważam):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
var
instrukcjiMożesz użyć
var
zdolności instrukcji do zdefiniowania (i przypisania) drugiej zmiennej tymczasowejindex
, oddzielonej przecinkami:2: Samowykonująca się funkcja anonimowa
Inną opcją jest samowykonująca się anonimowa funkcja:
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 go użyć do wprowadzenia efektów ubocznych, w tym przypadku ponownie przypisując do
value
:To działa, ponieważ
var value
jest 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
value
jest używane jako podwyrażenie w nawiasach: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 : y
naidx == -1 ? y : x
:źródło
indefOf
)var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);
zamiast używać przecinka.var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );
ponieważ jest tylko jednym parametrem.Dla liczb
Możesz użyć
Math.max()
funkcji.Zachowa granice wyniku od
0
aż do pierwszego wyniku większe niż0
w takim przypadku. I jeśli wynik zeindexOf
jest-1
to 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 (
||
):Musisz być z tym bardzo ostrożny, ponieważ w pierwszym przykładzie
indexOf
może powrócić0
i jeśli oszacujesz0 || -1
, zwróci,-1
ponieważ0
jest fałszywą wartością.źródło
3
czy"y"
nie ma w indeksie0
zsomeArray
?Math.max
przykładzie?indexOf
zwraca 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ępnieMath.max
ustaw granice od 0 do długości, aby usunąć szansę aby zwrócić -1,0
dopasowanego elementu w tablicy lub0
ustawić naMath.max()
; lub u operatora warunkowego w OP. Rozważvar value = Math.max( ["y"].indexOf("y"), 0 )
. Jak ustalasz, który produkt0
jest zwracany?0
przekazane doMath.max()
wywołania lub0
odzwierciedlające indeks"y"
wewnątrz tablicy?Niezupełnie, po prostu użyj innej zmiennej.
Twój przykład uogólnia coś takiego.
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.
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ą:
źródło
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
a
naBoolean
zwracafalse
,result
zostanie przypisana'fallback value'
, w przeciwnym razie wartośća
.Uważaj na przypadek krawędzi
a === 0
, który rzucafalse
iresult
(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';
źródło
indexOf()
nie można jej użyć w tym wzorcu.||
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ę.-1
. Ponownie, nie mogę mówić o JavaScript i jego dziwactwach, ale generalnie-1
był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.Użyj wyodrębnionej zmiennej refaktoryzacji :
Jest jeszcze lepiej z
const
zamiastvar
. Możesz także wykonać dodatkową ekstrakcję:W praktyce użyć więcej niż znaczące nazwy
index
,condition
ivalue
.źródło
Prawdopodobnie szukasz operatora koalescencji. Na szczęście możemy wykorzystać
Array
prototyp do stworzenia jednego:Można to dodatkowo uogólnić w Twoim przypadku, dodając parametr do funkcji:
źródło
for (let x in ['b','c']) console.log(x);
drukuje0
,1
,"coalesce"
.Osobiście wolę dwa warianty:
Czyste, jeśli, jak sugerował @slebetman
Oddzielna funkcja, która zamienia nieprawidłową wartość na domyślną, jak w tym przykładzie:
źródło
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:
Po prostu zadzwoń
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.
źródło
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):
można (i powinno się, biorąc pod uwagę wywołania funkcji) skrócić w następujący sposób:
Jeśli szukasz bardziej ogólnego rozwiązania, które zapobiega powtarzaniu się zmiennej w trójskładniku, na przykład:
gdzie
foo
pojawia się tylko raz. Odrzucenie rozwiązań formularza: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 tofalsey
:źródło
Użyj funkcji pomocniczej:
Teraz twój kod jest bardzo czytelny i nie ma powtórzeń.
Hierarchia problemów związanych z kodowaniem jest następująca:
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:
źródło
translateValueIfEqual
sądziłem, bardziej opisowa, ale zmieniłem ją po tym, jak ktoś pomyślał, że jest za długa. Podobnie jakNz
funkcja 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.Myślę, że
||
operator można dostosować doindexOf
: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ń.
źródło
Jest to proste rozwiązanie z bitowym NIE i wartością domyślną,
-1
która jest późniejsza do zera.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:
źródło
Możesz użyć ponownego przypisania:
&&
operatora do ponownego przypisania, ponieważ jeśli pierwszy warunek jest fałszywy, drugie wyrażenie nie zostanie ocenioneDawny.
Pokaż fragment kodu
źródło
someArray.indexOf
jest wykonywane tylko razvalue
.-1
i0
; inaczejmax()
byłaby najlepsza opcjaAgain, not seeking an answer to the exact question above
, co pozostawia pytanie interpretacji;)Biorąc pod uwagę przykładowy kod w pytaniu nie jest jasne, w jaki sposób zostać stwierdzone, że
3
jest lub nie jest ustawiony na indeks0
zsomeArray
.-1
zwrócona z.indexOf()
będzie wartościowa w tym przypadku, w celu wykluczenia domniemanego niezgodności, która może być zgodna.Jeśli
3
nie jest uwzględnione w tablicy,-1
zostanie zwrócone. Możemy dodać1
do wyniku of,.indexOf()
aby oszacować, żefalse
wynik jest-1
, gdzie następuje||
OR
operator i0
. Kiedyvalue
występuje odwołanie, odejmij,1
aby uzyskać indeks elementu tablicy lub-1
.Która prowadzi z powrotem po prostu używając
.indexOf()
i sprawdzanie-1
podif
warunkiem. Lub zdefiniowanievalue
wundefined
celu uniknięcia możliwego pomyłki co do rzeczywistego wyniku ocenianego stanu w odniesieniu do pierwotnego odniesienia.źródło
Trójskładnik jest jak if-else, jeśli nie potrzebujesz części else, dlaczego nie tylko pojedynczej, jeśli zamiast ..
źródło
W tym konkretnym przypadku możesz użyć zwarcia z
||
operatorem logicznym . Ponieważ0
jest to uważane za fałszywe, możesz dodać1
do swojego indeksu, więc jeśliindex+1
tak0
, otrzymasz prawą stronę logiki - lub jako wynik, w przeciwnym razie otrzymasz swójindex+1
. Ponieważ pożądany wynik jest równoważony1
, możesz odjąć1
od niego, aby uzyskać indeks:źródło