Простое решение для объединения функций фильтра с Javascript
Я много-много раз использовал функцию .filter () для изменения содержимого данного массива, но недавно мне потребовалось разделить правила фильтрации на несколько функций, чтобы потом я мог легко их протестировать.
Я много гуглил и нашел множество решений, но ни одно из них не соответствовало простоте того, которое я придумал сам. В этой статье показано, как преобразовать простую функцию обратного вызова, которую мы передаем в .filter (), в несколько отдельных функций, каждая со своей уникальной логикой.
Давайте рассмотрим простое использование функции фильтра, когда мы хотим, чтобы в массиве оставалось только значение от 1 до 10.
Обычно, если мы хотим, чтобы наше значение удовлетворяло более чем 1 условиям, мы реализуем это так:
const arr = [1, 2, 3, 4, 5] arr.filter(x => x > 1 && x < 10)
Однако, если мы хотим иметь отдельную функцию для проверки границ значения, которое мы разрешаем передавать, это будет выглядеть так:
const checkBoundaries = (value) => { if(value > 1 && value < 10) { return true; } return false; } arr.filter(checkBoundaries)
Что, если мы хотим поместить каждую проверку границ в отдельную функцию, чтобы сделать код более тестируемым и расширяемым в будущем? Затем нам нужно будет создать нашу собственную функцию combFilters.
Давайте сначала разделим наши проверки границ на 2 функции.
const upperBoundaryCheck = (value) => { if (value < 10) { return true; } return false; }; const lowerBoundaryCheck = (value) => { if (value > 1) { return true; } return false; };
Теперь мы можем создать функцию commonFilters, которая будет применять все правила фильтрации к входящему значению и будет возвращать единственное значение true или false.
В нашем случае мы хотим получить true, если все правила пройдут, иначе вернуть false. Вот как это будет реализовано:
const combineFilters = (...filters) => (item) => { return filters.map((filter) => filter(item)).every((x) => x === true); };
CombineFilters - это каррированная функция, которая сначала вызывается с функциями фильтра в качестве аргументов, а второй раз вызывается методом .filter () с текущим значением.
arr.filter(combineFilters(upperBoundaryCheck, lowerBoundaryCheck));
Чтобы сделать его еще более читабельным, мы можем взять функцию комбинированных фильтров вне вызова метода .filter () следующим образом:
const combinedFilters = combineFilters( upperBoundaryCheck, lowerBoundaryCheck ); arr.filter(combinedFilters)
Таким образом, мы можем добавить столько правил фильтрации, сколько захотим, чтобы объединить фильтры, не усложняя код для чтения, тестирования и сопровождения.
Смотрите полный код здесь: ССЫЛКА