Что такое Map?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Map в JavaScript/TypeScript — структура данных и применение
Map — это встроенная структура данных в JavaScript, которая позволяет хранить пары ключ-значение. Это мощный инструмент, особенно полезный в Node.js разработке.
Что такое Map?
Map — это упорядоченная коллекция пар [ключ, значение], где ключ и значение могут быть любого типа. В отличие от обычного объекта, Map имеет много преимуществ.
const map = new Map();
const map2 = new Map([['key1', 'value1'], ['key2', 'value2']]);
const userMap: Map<string, User> = new Map();
Основные методы Map
1. set() — добавление/обновление
map.set('count', 1).set('b', 2);
2. get() — получение значения
const value = map.get('count'); // 1
3. has() — проверка наличия ключа
if (map.has('count')) { ... }
4. delete() — удаление элемента
map.delete('count'); // true
5. clear() — очистка Map
map.clear();
6. size — количество элементов
console.log(map.size);
7. Итерация
for (const [key, value] of map.entries()) { ... }
for (const key of map.keys()) { ... }
for (const value of map.values()) { ... }
map.forEach((value, key) => { ... });
Map vs Object — сравнение
// ✅ Map — ключи любого типа
const mapWithObjKey = new Map();
const key = { id: 1 };
mapWithObjKey.set(key, 'value');
// ❌ Object — только строки и символы
const obj = {};
obj[{ id: 1 }] = 'value'; // Преобразует в "[object Object]"
// ✅ Map — итерация в порядке добавления
const map = new Map([['a', 1], ['b', 2]]);
// ✅ Map — встроенные методы
map.size;
map.has('a');
map.clear();
Практические примеры использования Map
1. Кеширование данных
@Injectable()
export class CacheService {
private cache: Map<string, { value: any; expiresAt: number }> = new Map();
set(key: string, value: any, ttlSeconds: number = 60) {
this.cache.set(key, {
value,
expiresAt: Date.now() + ttlSeconds * 1000,
});
}
get(key: string): any | null {
const cached = this.cache.get(key);
if (!cached) return null;
if (Date.now() > cached.expiresAt) {
this.cache.delete(key);
return null;
}
return cached.value;
}
}
2. Подсчёт частоты элементов
function countFrequency(arr: string[]): Map<string, number> {
const frequency = new Map<string, number>();
for (const item of arr) {
frequency.set(item, (frequency.get(item) ?? 0) + 1);
}
return frequency;
}
const result = countFrequency(['apple', 'banana', 'apple']);
// Map { 'apple' => 2, 'banana' => 1 }
3. Управление зависимостями (DI контейнер)
@Injectable()
export class ServiceContainer {
private services: Map<string | symbol, any> = new Map();
private singletons: Map<string | symbol, any> = new Map();
register(key: string | symbol, factory: () => any, singleton = false) {
this.services.set(key, { factory, singleton });
}
resolve(key: string | symbol): any {
const service = this.services.get(key);
if (!service) throw new Error(`Service not found`);
if (service.singleton) {
if (!this.singletons.has(key)) {
this.singletons.set(key, service.factory());
}
return this.singletons.get(key);
}
return service.factory();
}
}
4. Группировка данных
interface User {
id: number;
role: 'admin' | 'user';
name: string;
}
function groupUsersByRole(users: User[]): Map<string, User[]> {
const grouped = new Map<string, User[]>();
for (const user of users) {
if (!grouped.has(user.role)) {
grouped.set(user.role, []);
}
grouped.get(user.role)!.push(user);
}
return grouped;
}
5. Отслеживание активных сессий
@Injectable()
export class SessionService {
private sessions: Map<string, Session> = new Map();
createSession(userId: string, data: any): string {
const sessionId = generateUUID();
this.sessions.set(sessionId, {
userId,
data,
createdAt: new Date(),
lastActivityAt: new Date(),
});
return sessionId;
}
getSession(sessionId: string): Session | null {
return this.sessions.get(sessionId) ?? null;
}
deleteSession(sessionId: string): void {
this.sessions.delete(sessionId);
}
cleanupExpiredSessions(maxAgeMinutes: number = 30): void {
const now = new Date();
for (const [sessionId, session] of this.sessions) {
const ageMinutes = (now.getTime() - session.lastActivityAt.getTime()) / (1000 * 60);
if (ageMinutes > maxAgeMinutes) {
this.sessions.delete(sessionId);
}
}
}
}
6. WeakMap для приватных данных
class User {
private privateData: WeakMap<User, any> = new WeakMap();
setPrivate(key: any) {
this.privateData.set(this, key);
}
getPrivate() {
return this.privateData.get(this);
}
}
Производительность Map vs Object
Для больших наборов данных Map часто быстрее благодаря оптимизированной работе движка JavaScript.
Выводы
Map — это мощная структура данных, которая превосходит обычные объекты по гибкости. Основные преимущества:
- Ключи любого типа (не только строки)
- Гарантированный порядок элементов
- Встроенные методы (set, get, has, delete, clear, size)
- Лучшая производительность для больших наборов данных
Map широко используется для кеширования, группировки данных, управления состоянием, отслеживания сессий и в DI контейнерах. Это один из основных инструментов опытного Node.js разработчика.