Один проход по массиву: одновременный map и filter в JavaScript
Быстрый ответ
Если вам необходимо одновременно отфильтровать и преобразовать элементы массива, удобно будет применить метод reduce()
. Его особенность в том, что он эффективно собирает элементы, отобранные по избранному критерию, и образует из них новый массив.
const result = array.reduce((acc, item) => filterCondition(item) ? [...acc, mapTransformation(item)] : acc, []);
В качестве достойного примера, удвоим числа, которые больше двух:
const doubled = [1, 2, 3, 4].reduce((acc, n) => n > 2 ? [...acc, n * 2] : acc, []);
console.log(doubled); // Выведет [6, 8]
Два зайца одним выстрелом: одновременное применение фильтрации и трансформации
reduce()
— это не просто метод, это как бы философия программирования. Он позволяет вам сконструировать желаемый массив через консистентную обработку каждого элемента. Это высококлассный инструмент для совместного выполнения фильтрации и трансформации без необходимости многократных проходов по массиву.
Мастерство использования логических операторов при редукции
Логические операторы могут стать надёжным союзником в процессе фильтрации, позволяя пропустить только те элементы, которые удовлетворяют установленным критериям.
Стрелочные функции ES6: на пути к лаконичности
Синтаксическая особенность стрелочных функций ES6 сделает вашу функцию reduce
более конкретной, сжатой и стилево оснащённой:
const result = items.reduce((acc, item) => condition(item) ? acc.concat(transform(item)) : acc, []);
Визуализация
Представим задачу выбора только зелёных фруктов, за исключением яблок, на живописном фруктовом рынке:
Корзина с фруктами: [🍏, 🍎, 🍐, 🥝, 🍏, 🍇]
Используем наш фильтр и выделим только зелёные фрукты:
const isGreenFruit = fruit => fruit.color === 'green' && fruit.type !== 'apple';
И вуаля — вот ваш идеально отсортированный набор:
Фильтрованный список: [🍐, 🥝, 🍇]
Таким образом, вы виртуозно совместили фильтрацию и трансформацию, выполненные за одну итерацию!
Современные инструменты: flatMap
и lodash как надёжные помощники
Сила flatMap
в обработке массивов
Метод flatMap()
сочетает в себе мощь маппинга и фильтрации. Он становится незаменимым помощником, когда вы сталкиваетесь с необходимостью получить различные результаты для каждого элемента массива.
const modified = items.flatMap(item => condition(item) ? [transform(item)] : []);
Поддержка от lodash
В случае более сложных задач у вас всегда есть библиотеки, вроде lodash, которые предлагают готовые решения для продвинутых операций, включая _.transform
.
const _ = require('lodash');
const transformed = _.transform(items, (result, value) => {
if (condition(value)) {
result.push(transform(value));
}
}, []);
Производительность и поддерживаемость кода
Производительность важна, но она не главное
Производительность зависит от размера массива и сложности использованных операций. Важно осуществлять сравнение различных методов, таких как reduce
, flatMap
и цепочку filter().map()
.
Код должен совершенствоваться со временем
Читабельность кода — критический критерий при выборе способа итерации. reduce
способен решить задачу в одной строке, но иногда более развёрнутый код облегчает отладку и понимание в дальнейшем.
Деструктуризация для чистоты кода
Деструктуризация обеспечивает прямой доступ к свойствам элементов и делает код более понятным:
const result = items.reduce((acc, { key1, key2 }) => condition(key1, key2) ? [...acc, transform(key1, key2)] : acc, []);
Баланс между ясностью и лаконичностью
Главная задача разработчика – найти баланс между чистотой кода и его лаконичностью. Устанавливать приоритеты следует в пользу тех методов, которые наиболее понятны, и стоит учесть, оправдывают ли сокращения будущее усилие по изучению кода.