функциональное программирование javascript цепочка фильтра по умолчанию - PullRequest
0 голосов
/ 22 мая 2018

Есть ли способ отфильтровать массив, и если он не возвращает никаких объектов по умолчанию для параметра по умолчанию в одной цепочке?

например,

[1,2,3]
    .filter(isDivisibleByTen)
    // otherwise return whatever

Я мог бы написать это так

const result [1,2,3].filter(isDivisibleByTen) 
result ? result [0]

Ответы [ 4 ]

0 голосов
/ 22 мая 2018

Я добавлю более подробный вариант здесь.Это решение использует 3 чистые функции, а затем объединяет их в конвейер.Это довольно типично для функционального программирования и имеет дополнительное преимущество - возможность тестировать функции изолированно, чтобы убедиться, что они выполняют именно то, что вы хотите.

(В качестве боковой панели другие языки, такие как elixir, создают цепочкуболее синтаксически приятный, но я отвлекся)

const defaultValue = "foobar";

const isDivisibleBy10 = n => n % 10 === 0;

const enforceDefault = numbers => numbers.length ? numbers : [defaultValue];

const unpackSingleton = numbers => numbers.length === 1 ? numbers[0] : numbers;


const pipeline = numbers =>
  unpackSingleton(
    enforceDefault(
      numbers.filter(isDivisibleBy10)
    )
  )

console.log(pipeline([2])); // no matches so returns default
console.log(pipeline([20])) // one match so returns the item

console.log(pipeline([1, 20, 10, 3])) // general case
0 голосов
/ 22 мая 2018

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

console.log([1,21,30].reduce((t, v) => { return v % 10 === 0 ? (t = 'default' ? [v] : t.concat(v)) : t; }, 'default'))

    console.log([1,21,35].reduce((t, v) => { return v % 10 === 0 ? (t = 'default' ? [v] : t.concat(v)) : t; }, 'default'))
0 голосов
/ 22 мая 2018

Решение 1. Без побочных эффектов.

Может быть, reduce - единственный метод Array, который предоставляет массив и может возвращать произвольное значение, поэтому вы можете использовать его:

[1,2,3]
    .filter(isDivisibleByTen)
    .reduce((_1, _2, _3, array) => array, 'defaultValue');

Это решение немного затрачивает процессорное время (циклы обходятся без массива), но его можно легко комбинировать с любой цепочкой.

Решение 2. Элегантное решение.

Вы можете добавить пользовательский метод в прототип Array, чтобы сделать его доступным в цепочке:

Array.prototype.filledOrDefault = function(defaultValue) {
    return this.length ? this : defaultValue;
}

[1,2,3]
    .filter(isDivisibleByTen)
    .filledOrDefault('defaultValue');

Это решение не рекомендуется, поскольку оно изменяет глобальное значение (Array), которое используетсядругие скрипты на странице.

0 голосов
/ 22 мая 2018

Вот что я думаю, что вы ищете в одной строке, но если результат ложный, filter () ничего не вернет.В демоверсии используется 1 filter().В демоверсии 2 map() используется с возвратом произвольного значения "default" в качестве альтернативного возврата.


Демо 1


console.log([1, 21, 30].filter(a => a % 10 === 0));

Демонстрация 2


console.log([1,21,30].map(a => a % 10 === 0 ? a : 'default'));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...