Wie definiere ich ein Array mit bedingten Elementen?

89

Wie kann ich bedingte Array-Elemente definieren? Ich möchte so etwas tun:

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

das funktioniert wie erwartet: ["foo", "bar"]

Aber wenn ich gesetzt condzu false, erhalte ich folgendes Ergebnis:["foo", false]

Wie kann ich ein Array mit einem bedingten Element definieren?

Manu Schiller
quelle

Antworten:

215

Sie können ein Array innerhalb eines Arrays verteilen, um das Array der Elemente sauber zu halten, wenn die Bedingung erfüllt ist false.

So geht's :

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

console.log(items)

Erklärungen :

Wie Sie sehen, gibt der ternäre Operator immer ein Array zurück.

Wenn die Bedingung erfüllt ist true, ['bar']wird ein leeres Array zurückgegeben [].

Danach verteilen wir ...das resultierende Array (aus der ternären Operation) und die Elemente des Arrays werden in das übergeordnete Array verschoben.

Wenn es keine Array-Elemente gibt (wenn die ternäre Prüfung durchgeführt wird false), wird nichts verschoben, was unser Ziel ist.


In einer anderen Antwort erklärte ich die gleiche Idee, aber für Objekte. Sie können es auch hier überprüfen .

Jordan Enev
quelle
1
Ich musste dies kürzlich tun und die Verwendung von Spread schien mir die naheliegendste Lösung zu sein. Ich bin froh, dass auch andere dieses Muster verwenden. Ich wollte es nicht zu kryptisch machen, aber ich werde damit rennen, da es populär genug zu sein scheint.
Brennan Cheung
Vielen Dank ~ !! Ich habe den Spread einfach nicht einmal als Option in
Betracht gezogen
Das ist sehr cool, hätte nicht gedacht, dass es einen Weg geben würde, dies zu tun, ohne das Array
nachträglich
1
Verdammt, deshalb liebe ich Ecmascript
Bobby
1
Hervorragende Lösung!
catch22
22

Ich würde das tun

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

Beachten Sie, dass dadurch auch falsche Werte entfernt werden, z. B. leere Zeichenfolgen.

Michael Bergquist Suarez
quelle
1
Ich mag die Idee. Aber Ihre Implementierung wäre falsch für [true && '']. Die leere Zeichenfolge würde herausgefiltert. Ich würde lieber eine Hilfsfunktion wie [foo] .filter (isNonBoolean) oder [foo] .stripBoolean () verwenden
Martin
@ Martin Ja, vielleicht könnte das in der Antwort näher ausgeführt werden. Ich werde es bearbeiten!
Michael Bergquist Suarez
Ich denke, es wird ein Problem geben, wenn ich ein Array wie dieses brauche: const arr = ['eins', 'zwei', falsch, wahr]; Aber die Idee ist gut für den wahren Wert :)
Sanjib Debnath
8

Sie können mit einem einfachen versuchen, wenn:

if(cond) {
    myArr.push("bar");
}
Sylvain Attoumani
quelle
7

Wenn Sie es wirklich als Einzeiler behalten möchten, können Sie Folgendes verwenden:

const cond = true;
const myArr = ["foo"].concat(cond ? ["bar"] : []);
James Thorpe
quelle
klug, war nützlich für mich für die bedingte Front des Arrays dhconst myArr = (cond ? ['item 1'] : []).concat(['item 2', 'item 3']);
Devonj
6

Sie haben nicht so viele andere Optionen als push:

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

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

Eine andere Idee besteht darin, möglicherweise Nullen hinzuzufügen und diese herauszufiltern:

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

myArr = myArr.filter((item) => item !== null);
Alberto Trindade Tavares
quelle
2

Es gibt verschiedene Möglichkeiten, aber die Art und Weise, wie Sie es tun, funktioniert für Javascript nicht wirklich.

Die einfachste Lösung wäre, nur eine if-Anweisung zu haben.

if (myCond) arr.push(element);

Es gibt auch filter, aber ich denke nicht, dass Sie das hier überhaupt wollen, da Sie anscheinend "Fügen Sie diese eine Sache hinzu, wenn diese eine Bedingung wahr ist", anstatt alles mit einer Bedingung zu vergleichen. Obwohl, wenn Sie wirklich ausgeflippt werden möchten, können Sie dies tun (würde nicht empfehlen, aber es ist cool, dass Sie können).

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

Grundsätzlich werden nur alle nicht wahren Werte herausgefiltert.

Adam LeBlanc
quelle
1
das scheint cool. Sie könnten auch var arr = ["a", cond && "bar"].filter(e => e);@Adam LeBlanc machen, aber Sie haben Recht, es ist wahrscheinlich Müll. aber cooler Müll;)
Manu Schiller
Es ist cool, aber ich würde nur für einen bedingten Wert davon abraten. Es ist besser für den allgemeinen Zweck geeignet, alle falschen Werte loszuwerden. Da Sie am Ende nur das gesamte Array für nur einen Wert durchgehen. Wenn Sie jedoch eine unbestimmte Anzahl von bedingten Werten haben, ist dies wahrscheinlich eine gute Lösung.
Adam LeBlanc
.filter (e => e) würde die leere Zeichenfolge herausfiltern.
Martin
1
const cond = false;
const myArr = ["foo", cond ? "bar" : null].filter(Boolean);

console.log(myArr)

Wird zu ["foo"] führen

Westman
quelle
0

Alternativer Ansatz: Vorfilter füllen statt Nachfiltern:

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

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

Kehrt zurück

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

Ich weiß, dass dies die Kurzschreibweise nicht löst (da es nicht funktioniert, egal was Sie versuchen), aber es kommt dem nahe.

Jankapunkt
quelle
0

Wenn Sie es6 verwenden, würde ich vorschlagen

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

Dieses Array enthält nur den Wert "van", wenn der Name gleich "van" ist, andernfalls wird er verworfen.

Naxxa Consulting
quelle
-1

wenn du benutzt Array.push

Sie können folgen

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

Ergebnis ist ["1"]

oder

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

Ergebnis ist ["1","2"]

Toffee
quelle
Wenn Sie ein checkund ein verwenden, ist pushIhre Lösung definitiv nicht die mit der höchsten Klarheit. Ich würde bei bleiben, if (check) foo.push( item );anstatt ein leeres Array im falschen Fall zu verbreiten.
Martin