Вивчай

Масиви — частина 2

JavaScript map filter reduce — кухня шефа де овочі фільтрують нарізають та зварюють у соусJavaScript map filter reduce — кухня шефа де овочі фільтрують нарізають та зварюють у соус

У минулому уроці ми навчилися створювати масиви та працювати з ними через цикли. Тепер вивчимо методи масивів — елегантніший та потужніший спосіб обробки даних.


forEach — виконати дію для кожного елемента

const fruits = ["яблуко", "банан", "вишня"];

fruits.forEach((fruit) => {
  console.log(fruit);
});
// "яблуко", "банан", "вишня"

// З індексом:
fruits.forEach((fruit, index) => {
  console.log(`${index}: ${fruit}`);
});

forEach — альтернатива for...of, але не може використовувати break.


map — перетворення кожного елемента

Створює новий масив, де кожен елемент трансформовано:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((num) => num * 2);

console.log(doubled);  // [2, 4, 6, 8, 10]
console.log(numbers);  // [1, 2, 3, 4, 5] — оригінал не змінився!

Практичні приклади

// Імена з великої літери
const names = ["олексій", "марія", "іван"];
const capitalized = names.map((name) => name[0].toUpperCase() + name.slice(1));
// ["Олексій", "Марія", "Іван"]

// Витягнути одне поле з об'єктів
const users = [
  { name: "Олексій", age: 25 },
  { name: "Марія", age: 30 },
];
const userNames = users.map((user) => user.name);
// ["Олексій", "Марія"]
Порада

map — один з найчастіших методів. Використовуй його замість цикла for з push, коли потрібно перетворити масив. Він чистіший і зрозуміліший.


filter — відбір за умовою

Створює новий масив тільки з елементів, що відповідають умові:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const even = numbers.filter((num) => num % 2 === 0);
console.log(even); // [2, 4, 6, 8, 10]

const big = numbers.filter((num) => num > 5);
console.log(big); // [6, 7, 8, 9, 10]

Практичні приклади

const students = [
  { name: "Олексій", grade: 85 },
  { name: "Марія", grade: 92 },
  { name: "Іван", grade: 67 },
  { name: "Анна", grade: 95 },
];

// Відмінники (>= 90)
const topStudents = students.filter((s) => s.grade >= 90);
// [{ name: "Марія", grade: 92 }, { name: "Анна", grade: 95 }]

// Ті, хто не склав (< 70)
const failed = students.filter((s) => s.grade < 70);
// [{ name: "Іван", grade: 67 }]

find — знайти перший елемент

Повертає перший елемент, що відповідає умові (або undefined):

const numbers = [3, 7, 12, 5, 18];

const firstBig = numbers.find((num) => num > 10);
console.log(firstBig); // 12 (перший, що > 10)

const notFound = numbers.find((num) => num > 100);
console.log(notFound); // undefined

findIndex — індекс першого відповідного

const users = [
  { id: 1, name: "Олексій" },
  { id: 2, name: "Марія" },
  { id: 3, name: "Іван" },
];

const idx = users.findIndex((u) => u.id === 2);
console.log(idx); // 1
МетодПовертаєСкільки елементів
filterМасивВсі відповідні
findЕлементПерший відповідний
findIndexЧисло (індекс)Індекс першого

reduce — агрегація в одне значення

Найпотужніший метод масивів. "Зводить" масив до одного значення:

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

const sum = numbers.reduce((accumulator, current) => {
  return accumulator + current;
}, 0);

console.log(sum); // 15

Як працює (крок за кроком):

Початкове значення: 0
Ітерація 1: acc=0  + current=1 → 1
Ітерація 2: acc=1  + current=2 → 3
Ітерація 3: acc=3  + current=3 → 6
Ітерація 4: acc=6  + current=4 → 10
Ітерація 5: acc=10 + current=5 → 15
Результат: 15

Практичні приклади

// Сума цін
const prices = [29.99, 9.99, 49.99, 14.99];
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 104.96

// Підрахунок елементів
const votes = ["так", "ні", "так", "так", "ні", "так"];
const result = votes.reduce((counts, vote) => {
  counts[vote] = (counts[vote] || 0) + 1;
  return counts;
}, {});
console.log(result); // { так: 4, ні: 2 }
Порада

reduce — потужний, але не завжди потрібний. Для простої суми — так. Але якщо reduce стає складним, розбий на filter + map або використай цикл.


sort — сортування

// Рядки — працює за замовчуванням
const fruits = ["вишня", "яблуко", "банан"];
fruits.sort();
console.log(fruits); // ["банан", "вишня", "яблуко"]
Увага

sort()мутуючий метод: він змінює оригінальний масив (на відміну від map/filter, які повертають новий). Якщо потрібно зберегти оригінал, спочатку зроби копію: [...array].sort(). Більше про мутуючі vs немутуючі методи — в уроці про мутабельність.

Сортування чисел — обережно!

const numbers = [10, 2, 30, 4, 5];
numbers.sort();
console.log(numbers); // [10, 2, 30, 4, 5] — ❌ Сортує як рядки!

Правильно — передати функцію порівняння:

const numbers = [10, 2, 30, 4, 5];

// Від меншого до більшого
numbers.sort((a, b) => a - b);
console.log(numbers); // [2, 4, 5, 10, 30]

// Від більшого до меншого
numbers.sort((a, b) => b - a);
console.log(numbers); // [30, 10, 5, 4, 2]

Сортування об'єктів

const students = [
  { name: "Олексій", grade: 85 },
  { name: "Марія", grade: 92 },
  { name: "Іван", grade: 67 },
];

// За оцінкою (від найвищої)
students.sort((a, b) => b.grade - a.grade);
// Марія (92), Олексій (85), Іван (67)

Ланцюжки методів (chaining)

Методи можна з'єднувати в ланцюжки:

const students = [
  { name: "Олексій", grade: 85 },
  { name: "Марія", grade: 92 },
  { name: "Іван", grade: 67 },
  { name: "Анна", grade: 95 },
];

// Імена відмінників, відсортовані за оцінкою
const topNames = students
  .filter((s) => s.grade >= 90)     // [Марія, Анна]
  .sort((a, b) => b.grade - a.grade) // [Анна, Марія]
  .map((s) => s.name);               // ["Анна", "Марія"]

console.log(topNames);

Підсумок

  • map — перетворити кожен елемент → новий масив
  • filter — відібрати за умовою → новий масив
  • find — знайти перший відповідний → елемент або undefined
  • reduce — звести до одного значення (сума, підрахунок)
  • sort — сортування (змінює оригінал! для чисел потрібна (a, b) => a - b)
  • Chainingarray.filter().sort().map() — елегантна обробка даних

Що далі?

У наступному уроці вивчимо об'єкти — структури даних з іменованими полями.

Інфо

Корисні посилання: