JS Tower
JavaScript & TypeScriptМодуль 4: Массивы и объекты

Методы перебора

forEach, map, filter, reduce и другие

Цель урока

В этом уроке ты научишься:

  • Перебирать массивы функциональными методами
  • Трансформировать и фильтровать данные
  • Использовать reduce для агрегации

Важно

Эти методы не изменяют исходный массив (кроме forEach).


forEach

Выполняет функцию для каждого элемента:

let fruits = ["яблоко", "банан", "апельсин"];

fruits.forEach((fruit, index) => {
  console.log(index + ": " + fruit);
});
// 0: яблоко
// 1: банан
// 2: апельсин

Ничего не возвращает

forEach всегда возвращает undefined. Для создания нового массива используй map.


map

Создаёт новый массив, применяя функцию к каждому элементу:

let numbers = [1, 2, 3, 4, 5];

let doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5] — не изменился

Практические примеры

// Извлечение свойств
let users = [
  { name: "Иван", age: 25 },
  { name: "Мария", age: 22 }
];

let names = users.map(user => user.name);
console.log(names); // ["Иван", "Мария"]

// Форматирование
let prices = [100, 200, 300];
let formatted = prices.map(p => p + " ₽");
console.log(formatted); // ["100 ₽", "200 ₽", "300 ₽"]

filter

Создаёт новый массив с элементами, прошедшими проверку:

let numbers = [1, 2, 3, 4, 5, 6];

let even = numbers.filter(n => n % 2 === 0);
console.log(even); // [2, 4, 6]

Практические примеры

let users = [
  { name: "Иван", age: 25, active: true },
  { name: "Мария", age: 17, active: true },
  { name: "Пётр", age: 30, active: false }
];

// Только совершеннолетние
let adults = users.filter(u => u.age >= 18);

// Только активные
let active = users.filter(u => u.active);

// Комбинация условий
let activeAdults = users.filter(u => u.age >= 18 && u.active);

find и findIndex

find — первый подходящий элемент

let users = [
  { id: 1, name: "Иван" },
  { id: 2, name: "Мария" },
  { id: 3, name: "Пётр" }
];

let user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Мария" }

let notFound = users.find(u => u.id === 99);
console.log(notFound); // undefined

findIndex — индекс первого подходящего

let numbers = [10, 20, 30, 40];

let index = numbers.findIndex(n => n > 25);
console.log(index); // 2

let notFound = numbers.findIndex(n => n > 100);
console.log(notFound); // -1

some и every

some — хотя бы один

let numbers = [1, 2, 3, 4, 5];

console.log(numbers.some(n => n > 3));  // true
console.log(numbers.some(n => n > 10)); // false

every — все

let numbers = [2, 4, 6, 8];

console.log(numbers.every(n => n % 2 === 0)); // true
console.log(numbers.every(n => n > 5));       // false

reduce

Сворачивает массив в одно значение:

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

let numbers = [1, 2, 3, 4, 5];

let sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15

let product = numbers.reduce((acc, n) => acc * n, 1);
console.log(product); // 120

Практические примеры

// Максимум
let numbers = [5, 2, 9, 1, 7];
let max = numbers.reduce((a, b) => a > b ? a : b);
console.log(max); // 9

// Подсчёт
let fruits = ["яблоко", "банан", "яблоко", "апельсин", "банан", "банан"];
let count = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});
console.log(count); // { яблоко: 2, банан: 3, апельсин: 1 }

// Группировка
let users = [
  { name: "Иван", role: "admin" },
  { name: "Мария", role: "user" },
  { name: "Пётр", role: "admin" }
];

let byRole = users.reduce((acc, user) => {
  if (!acc[user.role]) acc[user.role] = [];
  acc[user.role].push(user);
  return acc;
}, {});

Цепочки методов

let users = [
  { name: "Иван", age: 25, salary: 50000 },
  { name: "Мария", age: 17, salary: 30000 },
  { name: "Пётр", age: 30, salary: 70000 },
  { name: "Анна", age: 22, salary: 45000 }
];

// Средняя зарплата взрослых
let avgSalary = users
  .filter(u => u.age >= 18)
  .map(u => u.salary)
  .reduce((sum, s, i, arr) => sum + s / arr.length, 0);

console.log(avgSalary); // 55000

Сводная таблица

МетодВозвращаетНазначение
forEachundefinedПеребор
mapНовый массивТрансформация
filterНовый массивФильтрация
findЭлемент/undefinedПоиск первого
findIndexИндекс/-1Индекс первого
somebooleanЕсть ли подходящий
everybooleanВсе ли подходят
reduceЛюбое значениеАгрегация

Практика

Задание 1: Удвоение

Задача: Создай массив удвоенных чисел.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
[2,4,6,8,10]

Задание 2: Фильтрация

Задача: Оставь только положительные числа.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
[5,8,10]

Задание 3: Сумма

Задача: Вычисли сумму с помощью reduce.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
100

Задание 4: Цепочка

Задача: Найди сумму квадратов чётных чисел.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
56

Проверь себя

  1. Чем map отличается от forEach?
  2. Что вернёт find, если элемент не найден?
  3. Для чего нужен второй аргумент reduce?