Что делают map, filter и reduce?


Функции map, filter и reduce — это встроенные функции высшего порядка, применяемые к коллекциям (массивам, спискам, последовательностям и т. д.) во многих языках программирования: JavaScript, Python, Swift, Java (через стримы), Ruby, Go (частично через собственную реализацию) и других. Они являются основой функционального подхода к обработке данных, позволяя писать декларативный, лаконичный и читаемый код.

1. map — отображение (трансформация) коллекции

Что делает:

Функция map применяет переданную функцию ко всем элементам коллекции, возвращая новую коллекцию с теми же размерами, но с изменёнными значениями.

Сигнатура (на примере JavaScript):

array.map(callback(currentValue, index, array))  newArray

Сигнатура (на примере Swift):

array.map { element in
// return transformedElement
}

Пример:

JavaScript:

const numbers = \[1, 2, 3\];
const doubled = numbers.map(x => x \* 2); // \[2, 4, 6\]

Swift:

let numbers = \[1, 2, 3\]
let doubled = numbers.map { $0 \* 2 } // \[2, 4, 6\]

Python:

numbers = \[1, 2, 3\]
doubled = list(map(lambda x: x \* 2, numbers)) # \[2, 4, 6\]

Ключевые особенности:

  • Не изменяет исходную коллекцию;

  • Возвращает новый массив/список;

  • Используется для трансформации данных.

2. filter — фильтрация по условию

Что делает:

Функция filter отбирает элементы, удовлетворяющие переданному условию (булевому выражению). Возвращается новая коллекция с подмножеством элементов.

Сигнатура (JavaScript):

array.filter(callback(currentValue, index, array))  newArray

Пример:

JavaScript:

const numbers = \[1, 2, 3, 4, 5\];
const even = numbers.filter(x => x % 2 === 0); // \[2, 4\]

Python:

numbers = \[1, 2, 3, 4, 5\]
even = list(filter(lambda x: x % 2 == 0, numbers)) # \[2, 4\]

Swift:

let numbers = \[1, 2, 3, 4, 5\]
let even = numbers.filter { $0 % 2 == 0 } // \[2, 4\]

Ключевые особенности:

  • Возвращает коллекцию с теми же типами элементов, но может быть короче;

  • Часто используется для отсеивания «мусора» или выборки нужных значений;

  • Исходная коллекция не модифицируется.

3. reduce — свёртка коллекции в одно значение

Что делает:

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

Сигнатура (JavaScript):

array.reduce(callback(accumulator, currentValue, index, array), initialValue)

Сигнатура (Swift):

array.reduce(initialResult) { accumulator, element in
// return newAccumulator
}

Пример:

#### **JavaScript — сумма всех элементов:**
const numbers = \[1, 2, 3, 4\];
const sum = numbers.reduce((acc, curr) => acc + curr, 0); // 10

Python:

from functools import reduce
numbers = \[1, 2, 3, 4\]
sum = reduce(lambda acc, x: acc + x, numbers, 0) # 10

Swift:

let numbers = \[1, 2, 3, 4\]
let sum = numbers.reduce(0) { $0 + $1 } // 10

Другие применения reduce:

  • Сложение/умножение;

  • Объединение строк;

  • Построение объекта из массива;

  • Построение словарей, хэш-таблиц и пр.

Пример — превращение массива в объект (JavaScript):

const arr = \["a", "b", "c"\];
const obj = arr.reduce((acc, key, idx) => {
acc\[key\] = idx;
return acc;
}, {});
// { a: 0, b: 1, c: 2 }

4. Отличия между map, filter и reduce

Функция Описание Результат Входная функция возвращает Тип результата
map Преобразует каждый элемент Коллекция такого же размера Новый элемент Массив
--- --- --- --- ---
filter Отбирает элементы по условию Коллекция меньшего или равного размера true или false Массив
--- --- --- --- ---
reduce Сводит к одному значению Одно значение (любой тип) Новый аккумулятор Любой
--- --- --- --- ---

5. Вложенные примеры

Комбинирование функций:

const data = \[1, 2, 3, 4, 5, 6\];
// Сначала отфильтруем чётные, затем умножим их на 10
const result = data
.filter(x => x % 2 === 0) // \[2, 4, 6\]
.map(x => x \* 10) // \[20, 40, 60\]
.reduce((a, b) => a + b, 0); // 120

6. Применение на практике

  • map: преобразование данных из одного формата в другой (например, чисел в строки, объектов в DOM-элементы).

  • filter: фильтрация входных данных, удаление невалидных записей, отбор нужных элементов.

  • reduce: подсчёт суммы, объединение строк, агрегация статистики, построение новых структур данных.

7. Поведение и свойства

Не мутируют исходный массив:

Все три функции возвращают новые значения, не изменяя оригинальную коллекцию.

Функции высшего порядка:

Каждая принимает другую функцию в качестве аргумента, что делает их выразительными и гибкими.

Порядок выполнения:

Функции работают последовательно слева направо, особенно важно для reduce, где порядок влияет на результат.

8. Влияние на читаемость и масштабируемость

Использование этих функций позволяет:

  • писать чистый и читаемый код;

  • избегать явных циклов (for, while);

  • выразить намерение (что делается) вместо механики (как делается);

  • легко комбинировать логические шаги обработки данных;

  • избежать мутаций и побочных эффектов (в функциональном стиле).

9. Особенности в разных языках

Язык Поддержка map / filter / reduce Особенности
JavaScript Да (Array.prototype.*) Работает на массивах
--- --- ---
Python Да (map(), filter(), reduce()) reduce требует functools
--- --- ---
Swift Да (map, filter, reduce) Работают на всех коллекциях
--- --- ---
Ruby Да (.map, .select, .inject) Элементы перечисления
--- --- ---
Java Да (stream().map()) Через Stream API
--- --- ---
C# Да (.Select(), .Where(), .Aggregate()) LINQ
--- --- ---
Go Нет встроенно, реализуется вручную Используется for + append
--- --- ---
Haskell Да (map, filter, foldr) По умолчанию, в языке
--- --- ---

10. Когда не стоит использовать

  • Когда важна производительность на горячих участках: вложенные .map().filter().reduce() могут быть медленнее for.

  • Когда нужна более сложная логика, которую удобнее реализовать в for или forEach.

  • Когда нужен контроль над порядком, индексами, состоянием счётчиков и т. д. — обычный цикл может быть понятнее.