Если вы дошли до этого урока, то уже знаете, что такое массивы, циклы и функции. Теперь пришло время вывести ваши навыки на новый уровень. Мы погрузимся в методы .map()
, .filter()
и .reduce()
. Научимся комбинировать их и решать сложные задачи элегантно и эффективно.
Почему это важно? Потому что эти методы основа функционального программирования в JavaScript. Они делают код чище, короче и понятнее.
Что такое методы высшего порядка?
Прежде чем перейти к конкретным методам, давайте вспомним, что такое функции высшего порядка. Это функции, которые могут принимать другие функции в качестве аргументов или возвращать их. Именно так работают .map()
, .filter()
и .reduce()
. Они принимают callback-функции и применяют их к элементам массива.
Главное преимущество, это иммутабельность. Эти методы не изменяют исходный массив, а создают новый. Это безопасно и соответствует принципам функционального программирования.
Метод .map(): Преобразование данных
Ситуация: У вас есть массив чисел, и вам нужно создать новый массив, где каждое число умножено на 2.
Раньше вы бы использовали цикл for
, но сегодня научимся делать это в одну строку.
Как работает .map():
- Принимает callback-функцию.
- Вызывает эту функцию для каждого элемента массива.
- Возвращает новый массив с результатами вызовов.
Пример:
const numbers = [1, 2, 3, 4]; const doubled = numbers.map(num => num * 2); console.log(doubled); // [2, 4, 6, 8]
Разберем по шагам:
numbers
— исходный массив..map()
проходит по каждому элементу.num => num * 2
— стрелочная функция, которая умножает элемент на 2.- Результат сохраняется в новый массив
doubled
.
Где это пригодится:
- Преобразование данных из API (например, извлечение имен пользователей).
- Форматирование строк (добавление символов, изменение регистра).
Задача 1:
Дан массив температур в градусах Цельсия: [0, 15, 25, -5]
. Преобразуйте их в градусы Фаренгейта по формуле: F = C * 1.8 + 32
.
Решение:
const celsius = [0, 15, 25, -5]; const fahrenheit = celsius.map(c => c * 1.8 + 32); console.log(fahrenheit); // [32, 59, 77, 23]
Метод .filter()
: Фильтрация элементов
Ситуация: У вас есть массив пользователей, и вам нужно выбрать только тех, кто старше 18 лет.
Как работает .filter()
:
- Принимает callback-функцию, которая возвращает
true
илиfalse
. - Создает новый массив из элементов, для которых callback вернул
true
.
Пример:
const ages = [12, 25, 8, 30, 17]; const adults = ages.filter(age => age >= 18); console.log(adults); // [25, 30]
Разбор:
age >= 18
— условие фильтрации.- В новый массив
adults
попадают только элементы, удовлетворяющие условию.
Где это пригодится:
- Поиск элементов по критериям (например, товары определенной категории).
- Удаление «мусора» из данных (пустые строки, нули).
Задача 2:
Дан массив строк: ['JavaScript', 'Python', 'C++', 'Java', '', 'Ruby']
. Отфильтруйте пустые строки и языки с длиной названия больше 4 символов.
Решение:
const languages = ['JavaScript', 'Python', 'C++', 'Java', '', 'Ruby']; const filtered = languages.filter(lang => lang !== '' && lang.length > 4); console.log(filtered); // ['JavaScript', 'Python']
Метод .reduce(): Агрегация данных
Ситуация: Вам нужно вычислить сумму всех элементов массива, найти максимальное значение или объединить элементы в строку.
Как работает .reduce():
- Принимает callback-функцию и начальное значение аккумулятора (опционально).
- Callback получает аккумулятор (промежуточный результат) и текущий элемент.
- Возвращает финальное значение аккумулятора.
Пример: Сумма элементов
const numbers = [10, 20, 30]; const sum = numbers.reduce((acc, num) => acc + num, 0); console.log(sum); // 60
Разберем аргументы:
(acc, num) => acc + num
— функция, которая прибавляет текущий элемент к аккумулятору.0
— начальное значение аккумулятора.
Где это пригодится:
- Вычисление статистики (среднее, сумма, максимум).
- Преобразование массива в объект (например, группировка по категориям).
Задача 3:
Дан массив слов: ['functional', 'programming', 'is', 'awesome']
. Используйте .reduce()
, чтобы объединить их в одну строку через пробел.
Решение:
const words = ['functional', 'programming', 'is', 'awesome']; const sentence = words.reduce((acc, word) => acc + ' ' + word, '').trim(); console.log(sentence); // "functional programming is awesome"
Комбинирование методов
Вот где начинается магия! Методы можно объединять в цепочки для решения сложных задач.
Пример:
У вас есть массив товаров:
const products = [ { name: 'Laptop', price: 1000, category: 'electronics' }, { name: 'Shirt', price: 20, category: 'clothes' }, { name: 'Phone', price: 500, category: 'electronics' }, { name: 'Socks', price: 5, category: 'clothes' }, ];
Задача:
Вычислить общую стоимость всех электронных товаров.
Решение:
const total = products .filter(product => product.category === 'electronics') // Фильтруем .map(product => product.price) // Извлекаем цены .reduce((acc, price) => acc + price, 0); // Суммируем console.log(total); // 1500
Разбор:
.filter()
оставляет только электронику..map()
создает массив цен..reduce()
складывает цены.
Практические задачи
Закрепим знания на реальных примерах.
Задача 1: Рейтинг книг
Дан массив книг:
const books = [ { title: '1984', rating: 4.8, pages: 328 }, { title: 'Brave New World', rating: 4.0, pages: 288 }, { title: 'Fahrenheit 451', rating: 4.5, pages: 227 }, ];
Цель: Получить массив названий книг с рейтингом выше 4.3.
Используйте цепочку .filter() и .map().
Задача 2: Самый длинный комментарий
Дан массив комментариев:
const comments = [ { text: 'Cool!', likes: 15 }, { text: 'Awesome article', likes: 23 }, { text: 'Thanks!', likes: 5 }, ];
Цель: Найти комментарий с максимальным количеством лайков, используя .reduce()
.
Задача 2: Группировка по первым буквам
Дан массив имен: ['Alice', 'Bob', 'Anna', 'Charlie', 'Alex']
.
Цель: Создать объект, где ключи — первые буквы имен, а значения — массивы имен.
Пример результата:
{ A: ['Alice', 'Anna', 'Alex'], B: ['Bob'], C: ['Charlie'] }
Используйте .reduce() с аккумулятором-объектом.
Частые ошибки
- Забыли return в callback-функции:
Стрелочные функции с фигурными скобками требуют явногоreturn
.// Ошибка: arr.map(num => { num * 2 }); // Вернет [undefined, undefined...] // Правильно: arr.map(num => num * 2); // Или { return num * 2; }
- Использование методов для side effects:
.map()
,.filter()
,.reduce()
не должны изменять внешние переменные.
Сегодня вы сделали огромный шаг в освоении JavaScript. Методы высшего порядка это инструменты, которые сделают ваш код профессиональным и лаконичным. Практикуйтесь, решайте задачи и комбинируйте методы.
Полный курс «JavaScript для начинающих» доступен здесь: https://max-gabov.ru/javascript-dlya-nachinaushih.