Масиви — частина 2
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— знайти перший відповідний → елемент або undefinedreduce— звести до одного значення (сума, підрахунок)sort— сортування (змінює оригінал! для чисел потрібна(a, b) => a - b)- Chaining —
array.filter().sort().map()— елегантна обробка даних
Що далі?
У наступному уроці вивчимо об'єкти — структури даних з іменованими полями.
Корисні посилання:
- javascript.info: Методи масивів — повний гайд (українською)
- MDN: Array.prototype.reduce() — детально про reduce