Как определить массив с условными элементами?


101

как я могу определить элементы условного массива? я хочу сделать что-то вроде этого:

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

это работает как ожидалось: ["foo", "bar"]

Но если установить condна false, я получаю следующий результат:["foo", false]

Как я мог определить массив с условным элементом?


Ответы:


233

Вы можете распределить массив внутри массива, чтобы сохранить массив элементов в чистоте, когда условие есть false.

Вот как это сделать :

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

console.log(items)

Пояснения :

Как видите, тернарный оператор всегда возвращает массив.

Если условие - trueвозвращается ['bar'], в противном случае - пустой массив [].

После этого мы распределяем ...полученный массив (из тернарной операции), и элементы массива помещаются в родительский массив.

Если элементов массива нет (когда есть тройная проверка false), то ничего не будет отправлено , что и является нашей целью.


В другом ответе я объяснил ту же идею, но для объектов. Вы тоже можете проверить это здесь .


1
Недавно мне понадобилось это сделать, и использование спреда показалось мне наиболее очевидным решением. Рад, что другие тоже используют этот шаблон. Я не хотел делать его слишком загадочным, но я собираюсь использовать его, поскольку он кажется достаточно популярным.
Brennan Cheung

Большое спасибо ~ !! я просто даже не рассматривал спред как вариант
carinlynchin

Это очень круто, не думал, что есть способ сделать это без фильтрации массива постфактум
JDune

1
Блин, вот почему я люблю Ecmascript
anni

1
Отличное решение!
catch22,

22

Я бы сделал это

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

Обратите внимание, что это также удалит ложные значения, такие как пустые строки.


1
Мне нравится идея. Но ваша реализация будет неправильной для [true && '']. Пустая строка будет отфильтрована. Я бы предпочел использовать вспомогательную функцию вроде [foo] .filter (isNonBoolean) или [foo] .stripBoolean ()
Мартин

@Martin Да, может быть, об этом можно подробнее рассказать в ответе. Я пойду и отредактирую!
Майкл Бергквист Суарес

Думаю, возникнут проблемы, если мне понадобится такой массив: const arr = ['one', 'two', false, true]; Но идея хороша для истинной ценности :)
Санджиб Дебнат,


8

Если вы действительно хотите сохранить его как один лайнер, вы можете использовать:

const cond = true;
const myArr = ["foo"].concat(cond ? ["bar"] : []);

умно, мне пригодилось для условного фронта массива т.е.const myArr = (cond ? ['item 1'] : []).concat(['item 2', 'item 3']);
devonj

6

У вас не так много вариантов, кроме использования push:

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

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

Другая идея - потенциально добавить нули и отфильтровать их:

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

myArr = myArr.filter((item) => item !== null);

3
const cond = false;
const myArr = ["foo", cond ? "bar" : null].filter(Boolean);

console.log(myArr)

Результатом будет ["foo"]


2

Есть несколько разных способов, но то, как вы это делаете, не работает для Javascript.

Самым простым решением было бы иметь оператор if.

if (myCond) arr.push(element);

Также есть filter, но я не думаю, что это то, что вы здесь вообще хотите, поскольку вы, кажется, собираетесь «добавить это одно, если это одно условие истинно», а не проверять все на соответствие какому-то условию. Хотя, если вы хотите стать действительно причудливым, вы можете это сделать (не рекомендую, но здорово, что вы можете).

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

По сути, он просто отфильтрует все неверные значения.


1
это кажется крутым. вы также можете сделать var arr = ["a", cond && "bar"].filter(e => e);@Adam LeBlanc, но вы правы, это, вероятно, мусор. но крутая фигня;)
Ману Шиллер

Это круто, но я бы не советовал использовать одно условное значение. Он лучше подходит для общего назначения типа «Избавиться от всех ложных значений». Поскольку вы просто собираетесь пройти весь массив только для одного значения. Но если у вас неопределенное количество условных значений, то это, вероятно, хорошее решение.
Adam LeBlanc

.filter (e => e) отфильтрует пустую строку.
Мартин

0

Альтернативный подход: заполнение Pre-Filter вместо пост-фильтрации:

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

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

Возврат

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

Я знаю, что это не решает проблему сокращенной записи (поскольку она не сработает, что бы вы ни пытались), но это близко к этому.


0

если вы используете es6, я бы посоветовал

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

Этот массив будет содержать значение «van», только если имя равно «van», в противном случае оно будет отброшено.


-1

если вы используете Array.push

Вы можете следовать

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

Результат ["1"]

или

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

Результат ["1","2"]


Если вы собираетесь использовать a checkи a, pushваше решение определенно не будет самым ясным. Я бы придерживался if (check) foo.push( item );вместо того, чтобы распространять пустой массив в случае ложности.
Мартин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.