JS Tower
JavaScript & TypeScriptМодуль 4: Массивы и объекты

Set и Map

Коллекции уникальных значений и пар ключ-значение

Цель урока

В этом уроке ты научишься:

  • Работать с уникальными значениями через Set
  • Использовать Map для пар ключ-значение
  • Понимать WeakSet и WeakMap

Set — уникальные значения

Set хранит только уникальные значения любого типа.

Создание и добавление

let set = new Set();

set.add(1);
set.add(2);
set.add(2); // игнорируется
set.add("hello");

console.log(set); // Set(3) { 1, 2, "hello" }
console.log(set.size); // 3

Создание из массива

let arr = [1, 2, 2, 3, 3, 3];
let set = new Set(arr);

console.log(set); // Set(3) { 1, 2, 3 }

// Обратно в массив
let unique = [...set];
console.log(unique); // [1, 2, 3]

Основные методы

let set = new Set([1, 2, 3]);

// Проверка
console.log(set.has(2)); // true
console.log(set.has(5)); // false

// Удаление
set.delete(2);
console.log(set); // Set(2) { 1, 3 }

// Очистка
set.clear();
console.log(set.size); // 0

Перебор

let set = new Set(["яблоко", "банан", "апельсин"]);

// for...of
for (let item of set) {
  console.log(item);
}

// forEach
set.forEach(item => console.log(item));

// В массив
let arr = Array.from(set);

Практические применения

// Удаление дубликатов
function unique(arr) {
  return [...new Set(arr)];
}

console.log(unique([1, 2, 2, 3, 3, 3])); // [1, 2, 3]

// Пересечение
function intersection(arr1, arr2) {
  let set2 = new Set(arr2);
  return arr1.filter(x => set2.has(x));
}

console.log(intersection([1, 2, 3], [2, 3, 4])); // [2, 3]

// Разность
function difference(arr1, arr2) {
  let set2 = new Set(arr2);
  return arr1.filter(x => !set2.has(x));
}

console.log(difference([1, 2, 3], [2, 3, 4])); // [1]

Map — пары ключ-значение

Map хранит пары ключ-значение, где ключом может быть что угодно.

Создание и добавление

let map = new Map();

map.set("name", "Иван");
map.set("age", 25);
map.set(1, "один");

console.log(map.get("name")); // "Иван"
console.log(map.get("age"));  // 25
console.log(map.size);        // 3

Ключи любого типа

let map = new Map();

let objKey = { id: 1 };
let funcKey = function() {};

map.set(objKey, "значение для объекта");
map.set(funcKey, "значение для функции");

console.log(map.get(objKey)); // "значение для объекта"

Отличие от объекта

В обычном объекте ключи — только строки и символы. В Map — любые значения.

Создание из массива

let map = new Map([
  ["name", "Иван"],
  ["age", 25],
  ["city", "Москва"]
]);

console.log(map.get("name")); // "Иван"

Основные методы

let map = new Map([["a", 1], ["b", 2]]);

// Проверка
console.log(map.has("a")); // true
console.log(map.has("c")); // false

// Удаление
map.delete("a");
console.log(map.size); // 1

// Очистка
map.clear();

Перебор

let map = new Map([
  ["name", "Иван"],
  ["age", 25]
]);

// for...of
for (let [key, value] of map) {
  console.log(key + ": " + value);
}

// Ключи
for (let key of map.keys()) {
  console.log(key);
}

// Значения
for (let value of map.values()) {
  console.log(value);
}

// forEach
map.forEach((value, key) => {
  console.log(key + ": " + value);
});

Преобразования

// Map → Object
let map = new Map([["a", 1], ["b", 2]]);
let obj = Object.fromEntries(map);
console.log(obj); // { a: 1, b: 2 }

// Object → Map
let obj2 = { x: 10, y: 20 };
let map2 = new Map(Object.entries(obj2));
console.log(map2.get("x")); // 10

WeakSet и WeakMap

Слабые ссылки — не препятствуют сборке мусора.

WeakSet

let weakSet = new WeakSet();

let obj1 = { name: "Объект 1" };
let obj2 = { name: "Объект 2" };

weakSet.add(obj1);
weakSet.add(obj2);

console.log(weakSet.has(obj1)); // true

// Ограничения:
// - Только объекты
// - Нет size, нет перебора
// - Автоматическое удаление при GC

WeakMap

let weakMap = new WeakMap();

let user = { name: "Иван" };
weakMap.set(user, "метаданные");

console.log(weakMap.get(user)); // "метаданные"

// Когда user = null, данные автоматически удалятся

Сравнение

ObjectMapSet
КлючиСтроки/символыЛюбые
ПорядокНе гарантированГарантированГарантирован
РазмерВручную.size.size
Переборfor...infor...offor...of

Практика

Задание 1: Уникальные элементы

Задача: Удали дубликаты из массива.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
["a","b","c","d"]

Задание 2: Подсчёт

Задача: Подсчитай количество каждого слова.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
{"hello":3,"world":2,"js":1}

Задание 3: Пересечение

Задача: Найди общие элементы двух массивов.

Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
[3,4,5]

Проверь себя

  1. Чем Set отличается от массива?
  2. Чем Map отличается от объекта?
  3. Когда использовать WeakMap?