Jak zdefiniować tablicę z elementami warunkowymi?

107

jak mogę zdefiniować warunkowe elementy tablicy? chcę zrobić coś takiego:

const cond = true;
const myArr = ["foo", cond && "bar"];

to działa zgodnie z oczekiwaniami: ["foo", "bar"]

Ale jeśli mogę ustawić condaby false, uzyskać następujący wynik:["foo", false]

Jak mogę zdefiniować tablicę z elementem warunkowym?

Manu Schiller
źródło

Odpowiedzi:

252

Możesz rozłożyć tablicę wewnątrz tablicy, aby zachować czystość tablicy elementów, gdy warunek to false.

Oto jak możesz to zrobić :

// Will result in ['foo', 'bar']
const items = [
  'foo',
  ... true ? ['bar'] : [],
  ... false ? ['falsy'] : [],
]

console.log(items)

Objaśnienia :

Jak widać, operator trójargumentowy zawsze zwraca tablicę.

Jeśli warunek to true, to zwraca ['bar'], w przeciwnym razie pusta tablica [].

Następnie rozkładamy ...wynikową tablicę (z operacji trójskładnikowej) i elementy tablicy są wypychane do tablicy nadrzędnej.

Jeśli nie ma żadnych elementów tablicy (gdy jest sprawdzanie trójskładnikowe false), nic nie zostanie przesunięte, co jest naszym celem.


W innej odpowiedzi wyjaśniłem ten sam pomysł, ale dla przedmiotów. Można to sprawdzić za tutaj .

Jordan Enev
źródło
1
Ostatnio musiałem to zrobić i użycie spreadu wydawało mi się najbardziej oczywistym rozwiązaniem. Cieszę się, że inni również używają tego wzoru. Nie chciałem, aby było to zbyt tajemnicze, ale zamierzam z nim korzystać, ponieważ wydaje się wystarczająco popularny.
Brennan Cheung,
wielkie dzięki ~ !! po prostu nawet nie rozważałem spreadu jako opcji
carinlynchin
To jest bardzo fajne, nie sądziłem, że da się to zrobić bez filtrowania tablicy po fakcie
JDune
2
Cholera, dlatego kocham Ecmascript
anni
1
Doskonałe rozwiązanie!
catch22
25

Zrobiłbym to

[
  true && 'one',
  false && 'two',
  1 === 1 && 'three',
  1 + 1 === 9 && 'four'
].filter(Boolean) // ['one', 'three']

Zwróć uwagę, że spowoduje to również usunięcie fałszywych wartości, takich jak puste ciągi.

Michael Bergquist Suarez
źródło
1
Podoba mi się ten pomysł. Ale Twoja implementacja byłaby błędna dla [true && '']. Pusty ciąg zostałby odfiltrowany. Wolałbym raczej użyć funkcji pomocniczej, takiej jak [foo] .filter (isNonBoolean) lub [foo] .stripBoolean ()
Martin
@Martin Tak, może można to rozwinąć w odpowiedzi. Pójdę dalej i edytuję to!
Michael Bergquist Suarez
Myślę, że będzie problem, jeśli potrzebuję tablicy takiej jak ta: const arr = ['jeden', 'dwa', fałsz, prawda]; Ale pomysł jest dobry dla wartości truthy :)
Sanjib Debnath
10

Możesz spróbować z prostym, jeśli:

if(cond) {
    myArr.push("bar");
}
Sylvain Attoumani
źródło
8

Jeśli naprawdę chcesz zachować go jako jedną wkładkę, możesz użyć:

const cond = true;
const myArr = ["foo"].concat(cond ? ["bar"] : []);
James Thorpe
źródło
sprytny, był dla mnie przydatny do warunkowego przodu tablicy tj.const myArr = (cond ? ['item 1'] : []).concat(['item 2', 'item 3']);
devonj
6

Nie masz tak wielu opcji poza użyciem push:

const cond = true;
const myArr = ["foo"];

if (cond) myArr.push("bar");

Innym pomysłem jest potencjalne dodanie wartości null i odfiltrowanie ich:

const cond = true;
const myArr = ["foo", cond ? "bar" : null];

myArr = myArr.filter((item) => item !== null);
Alberto Trindade Tavares
źródło
3
const cond = false;
const myArr = ["foo", cond ? "bar" : null].filter(Boolean);

console.log(myArr)

Efektem będzie ["foo"]

Westmana
źródło
2

Jest kilka różnych sposobów, ale sposób, w jaki to robisz, nie będzie działał w przypadku Javascript.

Najłatwiejszym rozwiązaniem byłoby posiadanie po prostu instrukcji if.

if (myCond) arr.push(element);

Jest też filter, ale nie wydaje mi się, żebyś w ogóle tego chciał, ponieważ wydaje się, że wolisz „Dodaj tę jedną rzecz, jeśli ten jeden warunek jest prawdziwy” zamiast sprawdzać wszystko pod kątem jakiegoś warunku. Chociaż, jeśli chcesz naprawdę zaszaleć, możesz to zrobić (nie polecam, ale fajnie, że możesz).

var arr = ["a", cond && "bar"];
arr.filter( e => e)

Zasadniczo po prostu odfiltruje wszystkie nieprawdziwe wartości.

Adam LeBlanc
źródło
1
to wydaje się fajne. mógłbyś też zrobić var arr = ["a", cond && "bar"].filter(e => e);@Adam LeBlanc, ale masz rację, to prawdopodobnie śmieci. ale fajne śmieci;)
Manu Schiller
To fajne, ale odradzałbym to tylko dla jednej wartości warunkowej. Lepiej nadaje się do ogólnego celu typu „Pozbądź się wszystkich fałszywych wartości”. Ponieważ w końcu przejdziesz przez całą tablicę tylko dla jednej wartości. Ale jeśli masz nieokreśloną liczbę wartości warunkowych, prawdopodobnie jest to dobre rozwiązanie.
Adam LeBlanc
.filter (e => e) odfiltrowałoby pusty ciąg.
Martin
0

Alternatywne podejście: filtr wstępny wypełnij zamiast filtrowania końcowego:

const populate = function(...values) {
    return values.filter(function(el) {
        return el !== false
    });
};

console.log(populate("foo", true && "bar", false && "baz"))

Zwroty

(2) ["foo", "bar"]

Wiem, że to nie rozwiązuje notacji skróconej (ponieważ nie zadziała bez względu na to, co spróbujesz), ale zbliża się do tego.

Jankapunkt
źródło
0

jeśli używasz es6, proponuję

let array = [ "bike", "car", name === "van" ? "van" : null, "bus", "truck", ].filter(Boolean);

Ta tablica będzie zawierać wartość „van” tylko wtedy, gdy nazwa jest równa „van”, w przeciwnym razie zostanie odrzucona.

Konsultacje Naxxa
źródło
-1

Jeśli użyjesz Array.push

Możesz śledzić

var a = ["1"]
a.push(... !true ? ["2"] : [])

Wynik jest ["1"]

lub

var a = ["1"]
a.push(... true ? ["2"] : [])

Wynik jest ["1","2"]

jądrowy
źródło
Jeśli masz zamiar używać a checki a, pushTwoje rozwiązanie zdecydowanie nie jest tym, które jest najbardziej przejrzyste. Ja bym się trzymał if (check) foo.push( item );zamiast rozprzestrzeniać pustą tablicę w fałszywym przypadku.
Martin,