Як визначити масив за допомогою умовних елементів?


102

як я можу визначити елементи умовного масиву? я хочу зробити щось подібне:

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

це працює як слід: ["foo", "bar"]

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

Як я можу визначити масив за допомогою умовного елемента?


Відповіді:


236

Ви можете поширити масив всередині масиву, щоб зберегти масив елементів чистим, коли умова є 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 Так, можливо, це можна було б детально пояснити у відповіді. Я піду далі і відредагую це!
Michael Bergquist Suarez

Я думаю, що буде проблема, якщо мені потрібен такий масив: 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);@ Адама Леблана, але ви маєте рацію, це, мабуть, сміття. але круте сміття;)
Ману Шиллер

Це круто, але я б радив не використовувати лише одне умовне значення. Він краще підходить для загальних цілей типу "Позбудьтеся всіх помилкових значень". Оскільки ви просто закінчите перебирати весь масив лише для одного значення. Але якщо у вас невизначена кількість умовних значень, то це, мабуть, гарне рішення.
Адам Леблан,

.filter (e => e) відфільтрує порожній рядок.
Мартін

0

Альтернативний підхід: заповнення попереднього фільтра замість фільтрації після:

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.