Пошук уроків, статей та іншого контенту
Порівняєте Object, Map, Array і Set та оберете відповідну структуру для типових задач.
Структура даних визначає, як ви зберігатимете інформацію та які операції виконуватимете найчастіше.
Одна й та сама задача може бути реалізована через Object, Map, Array або Set, але кожен варіант має власне призначення:
Object — набір властивостей із ключами;
Map — колекція пар «ключ — значення»;
Array — впорядкована послідовність елементів;
Set — колекція унікальних значень.
Правильний вибір робить код зрозумілішим і зменшує кількість додаткових перевірок та перетворень.
Використовуйте Array, коли:
важливий порядок елементів;
елементи можуть повторюватися;
ви працюєте з індексами;
потрібно перебирати список;
потрібні методи map, filter, reduce, find тощо.
const tasks = [
{ id: 1, title: "Прочитати документацію", completed: true },
{ id: 2, title: "Написати код", completed: false },
{ id: 3, title: "Запустити тести", completed: false }
];
const incompleteTasks = tasks.filter((task) => !task.completed);
console.log(incompleteTasks);
// [
// { id: 2, title: "Написати код", completed: false },
// { id: 3, title: "Запустити тести", completed: false }
// ]
const titles = tasks.map((task) => task.title);
console.log(titles);
// ["Прочитати документацію", "Написати код", "Запустити тести"]Доступ до елемента за індексом має постійну складність:
const colors = ["red", "green", "blue"];
console.log(colors[1]); // "green"Якщо потрібно знайти елемент за значенням, зазвичай доводиться переглянути масив:
const users = [
{ id: 10, name: "Олена" },
{ id: 20, name: "Андрій" }
];
const user = users.find((item) => item.id === 20);
console.log(user);
// { id: 20, name: "Андрій" }Для невеликих масивів це цілком нормально. Але якщо пошук за ідентифікатором виконується часто або масив великий, краще використовувати Map.
Object зручно використовувати у двох основних випадках:
для опису сутності з відомими властивостями;
для простого словника, де ключі є рядками або символами.
const user = {
id: 42,
name: "Марія",
email: "maria@example.com",
isActive: true
};
console.log(user.name); // "Марія"
console.log(user.isActive); // trueТакий об'єкт описує одного користувача. Властивості мають різний зміст і формують структуру сутності.
const prices = {
bread: 35,
milk: 42,
apples: 58
};
console.log(prices.milk); // 42
console.log(prices["apples"]); // 58Ключі звичайного об'єкта — це рядки або символи. Якщо використати інше значення як ключ, JavaScript перетворить його на рядок:
const objectKeys = {};
objectKeys[1] = "числовий ключ";
objectKeys[true] = "булевий ключ";
console.log(objectKeys);
// { "1": "числовий ключ", "true": "булевий ключ" }Це може бути несподіваним, особливо якщо ключами мають бути об'єкти або масиви.
Для перевірки власної властивості об'єкта використовуйте Object.hasOwn:
const settings = {
theme: "dark"
};
console.log(Object.hasOwn(settings, "theme")); // true
console.log(Object.hasOwn(settings, "language")); // falseНе варто бездумно використовувати перевірку через key in object, якщо потрібно перевірити саме власні властивості. Оператор in також враховує властивості з прототипу.
Map призначений саме для зберігання пар «ключ — значення».
Використовуйте Map, коли:
ключі можуть мати будь-який тип;
потрібно часто додавати, отримувати або видаляти записи;
потрібно отримати розмір колекції через size;
важливий порядок додавання записів;
об'єкт використовується як ключ.
const userById = new Map();
userById.set(101, {
name: "Оксана",
role: "admin"
});
userById.set(202, {
name: "Петро",
role: "user"
});
console.log(userById.get(101));
// { name: "Оксана", role: "admin" }
console.log(userById.has(202)); // true
console.log(userById.size); // 2
userById.delete(202);
console.log(userById.has(202)); // falseНа відміну від звичайного об'єкта, Map зберігає тип ключа:
const values = new Map();
values.set(1, "число");
values.set("1", "рядок");
values.set(true, "булеве значення");
console.log(values.get(1)); // "число"
console.log(values.get("1")); // "рядок"
console.log(values.get(true)); // "булеве значення"Об'єкти також можуть бути ключами:
const firstUser = { id: 1 };
const secondUser = { id: 2 };
const roles = new Map();
roles.set(firstUser, "admin");
roles.set(secondUser, "editor");
console.log(roles.get(firstUser)); // "admin"Тут ключем є саме посилання на об'єкт. Інший об'єкт із такими самими властивостями буде іншим ключем:
console.log(roles.get({ id: 1 })); // undefinedMap зберігає записи в порядку їх додавання:
const scores = new Map([
["Олена", 95],
["Андрій", 88],
["Марія", 97]
]);
for (const [name, score] of scores) {
console.log(`${name}: ${score}`);
}Також доступні методи:
keys() — ітератор ключів;
values() — ітератор значень;
entries() — ітератор пар;
forEach() — перебір записів.
Set зберігає лише унікальні значення. Якщо додати значення повторно, колекція не збільшиться.
Використовуйте Set, коли:
потрібно видалити дублікати;
потрібно швидко перевіряти наявність значення;
важливо зберігати набір унікальних елементів.
const tags = new Set();
tags.add("javascript");
tags.add("web");
tags.add("javascript");
console.log(tags.size); // 2
console.log(tags.has("web")); // true
tags.delete("web");
console.log(tags.has("web")); // falseНайпростіший спосіб отримати масив унікальних значень:
const numbers = [4, 7, 4, 2, 7, 9, 2];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [4, 7, 2, 9]Set зберігає порядок першої появи значень.
Для примітивних значень Set визначає дублікати очікувано:
const values = new Set([1, 1, 2, 2, 3]);
console.log(values); // Set(3) { 1, 2, 3 }Але об'єкти порівнюються за посиланням:
const items = new Set();
items.add({ id: 1 });
items.add({ id: 1 });
console.log(items.size); // 2Обидва об'єкти мають однаковий вміст, але це два різні об'єкти в пам'яті. Якщо потрібно вважати їх однаковими за id, краще використовувати Map:
const uniqueUsers = new Map();
for (const user of [
{ id: 1, name: "Олена" },
{ id: 1, name: "Олена" },
{ id: 2, name: "Петро" }
]) {
uniqueUsers.set(user.id, user);
}
console.log([...uniqueUsers.values()]);
// [
// { id: 1, name: "Олена" },
// { id: 2, name: "Петро" }
// ]Оберіть Array:
const queue = ["first", "second", "third"];Він підходить для:
списку товарів;
результатів пошуку;
черги елементів;
колекції, яку потрібно сортувати або фільтрувати.
Оберіть Object:
const product = {
id: 7,
title: "Клавіатура",
price: 2500
};Можна використати Object:
const translations = {
hello: "Привіт",
goodbye: "До побачення"
};Якщо ключі мають бути різних типів або потрібні спеціальні операції над колекцією, оберіть Map:
const translations = new Map([
["hello", "Привіт"],
["goodbye", "До побачення"]
]);Оберіть Set:
const visitedPages = new Set([
"/",
"/about",
"/contact"
]);Оберіть Map:
const productsById = new Map([
[1, { id: 1, title: "Ноутбук" }],
[2, { id: 2, title: "Монітор" }]
]);
const product = productsById.get(2);
console.log(product.title); // "Монітор"У реальних програмах структури часто використовують разом.
Наприклад, можна зберігати список замовлень у Array, а для швидкого доступу до замовлення за ідентифікатором — окремий Map:
const orders = [
{ id: 1001, customer: "Олена", total: 1200 },
{ id: 1002, customer: "Андрій", total: 850 },
{ id: 1003, customer: "Марія", total: 2400 }
];
const ordersById = new Map(
orders.map((order) => [order.id, order])
);
console.log(ordersById.get(1002));
// { id: 1002, customer: "Андрій", total: 850 }
const expensiveOrders = orders.filter((order) => order.total > 1000);
console.log(expensiveOrders);
// [
// { id: 1001, customer: "Олена", total: 1200 },
// { id: 1003, customer: "Марія", total: 2400 }
// ]У цьому прикладі:
Array зберігає повний впорядкований список;
Map забезпечує зручний доступ за id;
метод filter працює зі списком для отримання підмножини.
Для вибору структури важливо враховувати не лише синтаксис, а й типові операції.
У середньому:
доступ до елемента масиву за індексом — O(1);
пошук елемента в масиві через find або includes — O(n);
пошук, додавання та видалення в Map — у середньому O(1);
перевірка, додавання та видалення в Set — у середньому O(1);
пошук властивості об'єкта — у середньому O(1).
Це усереднені характеристики реалізації. Вони не означають, що кожна операція завжди виконується за абсолютно однаковий час.
Наприклад, якщо потрібно багато разів перевіряти, чи є ідентифікатор у колекції, така реалізація може бути невдалою:
const ids = [10, 20, 30, 40, 50];
const containsId = ids.includes(40);Для невеликого масиву це не проблема. Для великої колекції з великою кількістю перевірок можна створити Set:
const idSet = new Set([10, 20, 30, 40, 50]);
console.log(idSet.has(40)); // trueconst names = ["Олена", "Петро", "Олена"];
const uniqueNames = new Set(names);
const namesAgain = [...uniqueNames];
console.log(namesAgain); // ["Олена", "Петро"]Для роботи з властивостями об'єкта використовуйте:
Object.keys() — масив ключів;
Object.values() — масив значень;
Object.entries() — масив пар.
const stock = {
apples: 12,
bananas: 8,
oranges: 15
};
console.log(Object.keys(stock));
// ["apples", "bananas", "oranges"]
console.log(Object.values(stock));
// [12, 8, 15]
console.log(Object.entries(stock));
// [
// ["apples", 12],
// ["bananas", 8],
// ["oranges", 15]
// ]Map можна перетворити на масив пар:
const prices = new Map([
["book", 300],
["pen", 40]
]);
const entries = [...prices];
console.log(entries);
// [["book", 300], ["pen", 40]]Масив пар можна перетворити назад на Map:
const data = [
["language", "JavaScript"],
["level", "intermediate"]
];
const metadata = new Map(data);
console.log(metadata.get("language")); // "JavaScript"Перед реалізацією поставте собі кілька запитань:
Чи потрібен порядок елементів?
Так — найімовірніше, Array.
Чи можуть значення повторюватися?
Ні — Set або Map.
Чи потрібен пошук за ключем?
Так — Map або Object.
Чи ключі можуть бути не лише рядками?
Так — Map.
Чи описує структура одну сутність із відомими полями?
Так — Object.
Чи потрібно часто перевіряти унікальність або наявність?
Так — Set.
Чи потрібно виконувати filter, map, sort і працювати з індексами?
Так — Array.
| Задача | Структура | |---|---| | Список повідомлень у чаті | Array | | Дані одного профілю | Object | | Кеш результатів за ключем | Map | | Список унікальних дозволів | Set | | Товари, індексовані за id | Map | | Результати пошуку в заданому порядку | Array | | Налаштування з відомими назвами | Object |
Не варто зберігати записи з довільними ключами як властивості масиву:
const users = [];
users["admin"] = { name: "Олена" };
console.log(users.length); // 0Таке значення не стало елементом масиву. Для словника використовуйте Object або Map.
const cache = {};
const request = { url: "/users" };
cache[request] = "результат";
console.log(Object.keys(cache)); // ["[object Object]"]Різні об'єкти можуть перетворитися на однаковий рядковий ключ. Для ключів-об'єктів використовуйте Map:
const cache = new Map();
const request = { url: "/users" };
cache.set(request, "результат");
console.log(cache.get(request)); // "результат"Set не порівнює об'єкти за вмістом:
const set = new Set();
set.add({ id: 1 });
set.add({ id: 1 });
console.log(set.size); // 2Якщо унікальність визначається конкретним полем, зберігайте об'єкти в Map за цим полем або спочатку створюйте ключі.
Map.size і Object.lengthДля Map кількість елементів отримують через size:
const map = new Map([
["a", 1],
["b", 2]
]);
console.log(map.size); // 2У звичайного об'єкта властивості length немає. Використовуйте Object.keys:
const object = {
a: 1,
b: 2
};
console.log(Object.keys(object).length); // 2Для Set також використовується size:
const set = new Set([1, 2, 3]);
console.log(set.size); // 3Не кожну колекцію потрібно зберігати в Array. Якщо основна операція — пошук за ключем, Map часто краще передає намір коду:
const userById = new Map();Назва та API одразу показують, що колекція індексована за ідентифікатором.
Array використовуйте для впорядкованих списків, індексів і функціональних операцій над колекцією.
Object підходить для опису сутностей і простих словників із рядковими ключами.
Map використовуйте для пар «ключ — значення», особливо коли ключі можуть мати різні типи або потрібні часті операції з колекцією.
Set зберігає лише унікальні значення та зручний для перевірки наявності.
Об'єкти й масиви порівнюються за посиланням, а не за вмістом.
Структури можна комбінувати: наприклад, використовувати Array для порядку і Map для швидкого доступу за ідентифікатором.
Обирайте структуру, виходячи з основних операцій: пошуку, вставки, видалення, перевірки унікальності та збереження порядку.