[Medium] Set & Map
1. Что такое Set и Map?
Что такое Set и Map?
Set и Map — две структуры данных, введённые в ES6.
Они лучше решают определённые задачи, чем обычные массивы/объекты.
Set
Определение: Set — это коллекция уникальных значений, аналогичная множеству в математике.
Характеристики:
- Хранимые значения уникальны
- Проверка равенства использует семантику
===для большинства значений - Сохраняет порядок вставки
- Может хранить значения любого типа (примитивы или объекты)
Базовое использование:
// создание Set
const set = new Set();
// добавление значений
set.add(1);
set.add(2);
set.add(2); // дубликат игнорируется
set.add('hello');
set.add({ name: 'John' });
console.log(set.size); // 4
console.log(set); // Set(4) { 1, 2, 'hello', { name: 'John' } }
// проверка наличия
console.log(set.has(1)); // true
console.log(set.has(3)); // false
// удаление
set.delete(2);
console.log(set.has(2)); // false
// очистка
set.clear();
console.log(set.size); // 0
Создание Set из массива:
// удаление дубликатов из массива
const arr = [1, 2, 2, 3, 3, 3];
const uniqueSet = new Set(arr);
console.log(uniqueSet); // Set(3) { 1, 2, 3 }
// преобразование обратно в массив
const uniqueArr = [...uniqueSet];
console.log(uniqueArr); // [1, 2, 3]
// сокращённая запись
const uniqueArr2 = [...new Set(arr)];
Map
Определение: Map — это коллекция ключ-значение, аналогичная объектам, но ключи могут быть любого типа.
Характеристики:
- Ключи могут быть любого типа (строка, число, объект, функция и т.д.)
- Сохраняет порядок вставки
- Имеет свойство
size - Итерация следует порядку вставки
Базовое использование:
// создание Map
const map = new Map();
// установка пар ключ-значение
map.set('name', 'John');
map.set(1, 'one');
map.set(true, 'boolean');
map.set({ id: 1 }, 'object key');
// получение значения
console.log(map.get('name')); // 'John'
console.log(map.get(1)); // 'one'
// проверка наличия ключа
console.log(map.has('name')); // true
// удаление
map.delete('name');
// размер
console.log(map.size); // 3
// очистка
map.clear();
Создание Map из массива:
// из двумерного массива
const entries = [
['name', 'John'],
['age', 30],
['city', 'Taipei'],
];
const map = new Map(entries);
console.log(map.get('name')); // 'John'
// из объекта
const obj = { name: 'John', age: 30 };
const map2 = new Map(Object.entries(obj));
console.log(map2.get('name')); // 'John'
2. Set vs Array
Разница между Set и Array
| Характеристика | Set | Array |
|---|---|---|
| Дубликаты | Не допускаются | Допускаются |
| Доступ по индексу | Не поддерживается | Поддерживается |
| Сложность поиска | O(1) в среднем | O(n) |
| Порядок вставки | Сохраняется | Сохраняется |
| Основные методы | add, has, delete | push, pop, indexOf |
Случаи использования:
// ✅ Set для уникальных значений
const userIds = new Set([1, 2, 3, 2, 1]);
console.log([...userIds]); // [1, 2, 3]
// ✅ Set для быстрой проверки наличия
const visitedPages = new Set();
visitedPages.add('/home');
visitedPages.add('/about');
if (visitedPages.has('/home')) {
console.log('Homepage already visited');
}
// ✅ Array, когда нужны индексы или дубликаты
const scores = [100, 95, 100, 90];
console.log(scores[0]); // 100
3. Map vs Object
Разница между Map и Object
| Характеристика | Map | Object |
|---|---|---|
| Тип ключа | Любой тип | String или Symbol |
| Размер | Свойство size | Ручной подсчёт |
| Ключи по умолчанию | Нет | Цепочка прототипов существует |
| Порядок итерации | Порядок вставки | Порядок вставки в современном JS |
| Производительность | Лучше при частом добавлении/удалении | Часто хорош для статических/простых структур |
| JSON | Напрямую не сериализуется | Нативная поддержка JSON |
Случаи использования:
// ✅ Map, когда ключи не строки
const userMetadata = new Map();
const user1 = { id: 1 };
const user2 = { id: 2 };
userMetadata.set(user1, { lastLogin: '2024-01-01' });
userMetadata.set(user2, { lastLogin: '2024-01-02' });
console.log(userMetadata.get(user1)); // { lastLogin: '2024-01-01' }
// ✅ Map для частого добавления/удаления
const cache = new Map();
cache.set('key1', 'value1');
cache.delete('key1');
cache.set('key2', 'value2');
// ✅ Object для статических структур + JSON
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
};
const json = JSON.stringify(config);
4. Распространённые вопросы для собеседования (Common Interview Questions)
Распространённые вопросы для собеседования
Вопрос 1: удаление дубликатов из массива
Реализуйте функцию для удаления дубликатов.
function removeDuplicates(arr) {
// ваша реализация
}
Нажмите, чтобы увидеть ответ
Способ 1: Set (рекомендуется)
function removeDuplicates(arr) {
return [...new Set(arr)];
}
console.log(removeDuplicates([1, 2, 2, 3, 3, 3])); // [1, 2, 3]
console.log(removeDuplicates(['a', 'b', 'a', 'c'])); // ['a', 'b', 'c']
Способ 2: filter + indexOf
function removeDuplicates(arr) {
return arr.filter((value, index) => arr.indexOf(value) === index);
}
Способ 3: reduce
function removeDuplicates(arr) {
return arr.reduce((acc, value) => {
if (!acc.includes(value)) {
acc.push(value);
}
return acc;
}, []);
}
Производительность:
- Set: O(n), быстрейший
- filter + indexOf: O(n²), медленнее
- reduce + includes: O(n²), медленнее