Domů O mně Služby Portfolio Učím Blog Kontakt
← Zpět na učím

04.12 Set

Výuka

Proč Set?

Set je vestavěná datová struktura pro uložení unikátních hodnot. Automaticky odstraňuje duplicity a poskytuje rychlé operace pro přidávání, odstran ování a kontrolu existence.

Proč to potřebujeme?

  • Odstranění duplicit - Rychle vyfiltruj duplicitní hodnoty z pole
  • Kontrola existence - Rychlejší než includes() u velkých kolekcí
  • Matematické operace - Sjednocení, průnik, rozdíl množin
  • Unikátní kolekce - Uložení unikátních ID, tagů, kategorií

Představ si to jako: Pytel s míčky - pokud hodíš dva stejné míčky dovnitř, Set si ponechá jen jeden. Nemůžeš mít duplicity.

Jak to funguje?

Set:
1. Ukládá UNIKÁTNÍ hodnoty (automaticky odstraňuje duplicity)
2. Hodnoty mohou být jakéhokoliv typu (čísla, stringy, objekty)
3. Zachovává pořadí vložení
4. Rychlé operace: add, has, delete (O(1) v průměru)
5. Porovnává podle SameValueZero (podobné ===, ale NaN === NaN)

Klíčové koncepty

  • Set - kolekce unikátních hodnot
  • Automatické odstranění duplicit - stejná hodnota se uloží jen jednou
  • size - počet unikátních prvků (ne length!)
  • Metody: add(), has(), delete(), clear()
  • Iterable - můžeš iterovat přes hodnoty (for...of, spread)
  • SameValueZero - porovnává hodnoty (NaN se považuje za stejné)

JavaScript

Příklad 1: Vytvoření Set a odstranění duplicit

// Prázdný Set
const set1 = new Set();
console.log(set1);
// → Set(0) {}

// Set s počátečními hodnotami (z pole)
const set2 = new Set([1, 2, 3, 4, 5]);
console.log(set2);
// → Set(5) {1, 2, 3, 4, 5}

// Automatické odstranění duplicit
const arr = [1, 2, 2, 3, 3, 3, 4];
const set3 = new Set(arr);
console.log(set3);
// → Set(4) {1, 2, 3, 4}

// Zpět na pole
const unique = [...set3];
console.log(unique);
// → [1, 2, 3, 4]

Co se stalo?

  • new Set() - vytvoří prázdný Set
  • new Set(arr) - vytvoří Set z pole (odstraní duplicity)
  • size - počet unikátních hodnot
  • [...set] - převod zpět na pole

Příklad 2: add() - přidání hodnot

const set = new Set();

// Přidej hodnoty
set.add(1);
set.add(2);
set.add(3);
console.log(set);
// → Set(3) {1, 2, 3}

// Duplicitní přidání se ignoruje
set.add(2);
console.log(set);
// → Set(3) {1, 2, 3} (stále jen 3 prvky!)

// Můžeš řetězit (chaining)
set.add(4).add(5).add(6);
console.log(set);
// → Set(6) {1, 2, 3, 4, 5, 6}

Co se stalo?

  • add(value) - přidá hodnotu (pokud ještě neexistuje)
  • Duplicitní hodnota se ignoruje (neudělá nic)
  • Vrací Set samotný → můžeš řetězit: set.add(1).add(2)

Příklad 3: has() - kontrola existence

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

console.log(set.has(2));
// → true (2 je v Setu)

console.log(set.has(9));
// → false (9 tam není)

// Rychlejší než includes() u velkých kolekcí
const arr = [1, 2, 3, 4, 5, ... /* tisíce prvků */];
const set2 = new Set(arr);

// ✅ Rychlé (O(1))
set2.has(1000);

// ⚠️ Pomalejší (O(n))
arr.includes(1000);

Co se stalo?

  • has(value) - vrací true/false
  • Rychlejší než includes() u velkých kolekcí
  • Průměrně O(1) (konstantní čas), includes je O(n)

Příklad 4: delete() a clear() - odstranění

const set = new Set([1, 2, 3, 4, 5]);

// Odstraň hodnotu
const removed = set.delete(3);
console.log(removed);
// → true (hodnota byla odstraněna)

console.log(set);
// → Set(4) {1, 2, 4, 5}

// Pokus o odstranění neexistující hodnoty
const notRemoved = set.delete(99);
console.log(notRemoved);
// → false (hodnota tam nebyla)

// Vymaž celý Set
set.clear();
console.log(set);
// → Set(0) {}
console.log(set.size);
// → 0

Co se stalo?

  • delete(value) - odstraní hodnotu, vrací true/false
  • clear() - vymaže všechny hodnoty
  • size - počet zbývajících prvků

Příklad 5: Iterace přes Set

const set = new Set(['a', 'b', 'c']);

// for...of
for (const value of set) {
  console.log(value);
}
// → a
// → b
// → c

// forEach
set.forEach(value => {
  console.log(value);
});
// → a
// → b
// → c

// Spread na pole
const arr = [...set];
console.log(arr);
// → ['a', 'b', 'c']

// keys() a values() jsou stejné (Set nemá klíče)
console.log([...set.keys()]);    // → ['a', 'b', 'c']
console.log([...set.values()]);  // → ['a', 'b', 'c']

Co se stalo?

  • Set je iterable - můžeš použít for...of
  • forEach funguje jako u pole
  • Zachovává pořadí vložení
  • keys() a values() jsou ekvivalentní (Set nemá klíče)

Příklad 6: Matematické operace - sjednocení, průnik, rozdíl

const A = new Set([1, 2, 3]);
const B = new Set([3, 4, 5]);

// SJEDNOCENÍ (union) - všechny unikátní prvky z obou
const union = new Set([...A, ...B]);
console.log(union);
// → Set(5) {1, 2, 3, 4, 5}

// PRŮNIK (intersection) - prvky společné pro obě množiny
const intersection = new Set([...A].filter(x => B.has(x)));
console.log(intersection);
// → Set(1) {3}

// ROZDÍL (difference) - A \ B (prvky v A, ale ne v B)
const difference = new Set([...A].filter(x => !B.has(x)));
console.log(difference);
// → Set(2) {1, 2}

// SYMETRICKÝ ROZDÍL - prvky jen v jedné množině
const symDiff = new Set([
  ...[...A].filter(x => !B.has(x)),
  ...[...B].filter(x => !A.has(x))
]);
console.log(symDiff);
// → Set(4) {1, 2, 4, 5}

Co se stalo?

  • Union: [...A, ...B] - sloučí a odstraní duplicity
  • Intersection: filtruj A, ponech jen prvky z B
  • Difference: filtruj A, vyhoď prvky z B
  • Symmetric difference: prvky jen v jedné množině

TypeScript

TypeScript přidává typovou kontrolu hodnot v Setu.

Stejné příklady s typy

// Set s typy
const set1: Set<number> = new Set([1, 2, 3]);
const set2: Set<string> = new Set(['a', 'b', 'c']);

// TypeScript inferuje typ z pole
const set3 = new Set([1, 2, 3]);  // Set<number>

// Chybová kontrola - nemůžeš přidat špatný typ
set1.add(4);   // ✅ OK
// set1.add('text');  // ❌ Error: Argument of type 'string' is not assignable to parameter of type 'number'

// has() vrací boolean
const exists: boolean = set1.has(2);

// Iterace s typy
for (const value of set1) {
  // value má typ number
  console.log(value * 2);
}

// Generická utility funkce
function toSet<T>(arr: T[]): Set<T> {
  return new Set(arr);
}

const numSet: Set<number> = toSet([1, 2, 2, 3]);
const strSet: Set<string> = toSet(['a', 'b', 'b', 'c']);

// Matematické operace s typy
const A: Set<number> = new Set([1, 2, 3]);
const B: Set<number> = new Set([3, 4, 5]);

const union: Set<number> = new Set([...A, ...B]);
const intersection: Set<number> = new Set([...A].filter(x => B.has(x)));

// ReadonlySet (TypeScript 3.4+)
const readonly: ReadonlySet<number> = new Set([1, 2, 3]);
// readonly.add(4);  // ❌ Error: Property 'add' does not exist on type 'ReadonlySet<number>'
console.log(readonly.has(2));  // ✅ OK - čtení je povoleno

TypeScript přidává:

  • Typovou kontrolu hodnot - nemůžeš přidat špatný typ
  • Inference typů - TypeScript pozná typ z pole
  • ReadonlySet - neměnný Set (jen čtení)
  • Generické funkce - typově bezpečné utility funkce

Rozdíl JS vs TS

JavaScript:

  • Set funguje bez typové kontroly
  • Můžeš přidat jakýkoli typ hodnoty
  • Flexibilnější, ale nebezpečnější

TypeScript:

  • Set má definovaný typ hodnot
  • TypeScript zkontroluje, že přidáváš správný typ
  • Bezpečnější, prevence chyb
// JavaScript - projde, ale matoucí
const set = new Set();
set.add(1);
set.add('text');
set.add(true);  // Všechny typy v jednom Setu

// TypeScript - konzistentní typ
const set: Set<number> = new Set();
set.add(1);
// set.add('text');  // ❌ Error

Tip

💡 Rychlé odstranění duplicit z pole:

// ✅ Nejrychlejší způsob
const arr = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(arr)];  // [1, 2, 3, 4]

// ❌ Pomalejší
const unique2 = arr.filter((v, i, a) => a.indexOf(v) === i);

💡 Set pro rychlé kontroly existence:

// ✅ Rychlé - Set.has() je O(1)
const validIds = new Set([1, 5, 10, 15, 20]);
if (validIds.has(userId)) {
  // ...
}

// ❌ Pomalejší - includes() je O(n)
const validIds = [1, 5, 10, 15, 20];
if (validIds.includes(userId)) {
  // ...
}

💡 Pozor na reference u objektů:

const set = new Set();
const obj1 = { name: 'Alice' };
const obj2 = { name: 'Alice' };

set.add(obj1);
set.add(obj2);

console.log(set.size);
// → 2 (různé reference, i když stejný obsah!)

set.add(obj1);  // Duplicitní reference
console.log(set.size);
// → 2 (stále 2 - obj1 už tam je)

Kvíz

Co vypíše tento kód?

const set = new Set([1, 2, 3]);
set.add(2);
set.add(4);
set.delete(3);
console.log(set.size);

- - Start: Set(3) {1, 2, 3} (size = 3)

  • set.add(2) - 2 už tam je, ignoruje se (size = 3)
  • set.add(4) - přidá 4 (size = 4)
  • set.delete(3) - odstraní 3 (size = 3)
  • Finální: Set(3) {1, 2, 4}

- Zapomněl jsi na delete(3)

- add(2) se ignoruje (duplicita)

- Chybný výpočet

Důležité: Set automaticky ignoruje duplicity - add(2) když 2 už tam je neudělá nic!

Důležité: Set automaticky ignoruje duplicity - add(2) když 2 už tam je neudělá nic!

🎯 Závěrečný projekt

Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.

Zobrazit podrobnosti projektu →

Připraveni začít?

Zaregistrujte se a získejte přístup ke všem dílům tohoto seriálu

Kontaktujte mě

Informace o seriálu

Obtížnost

Délka

Cca 480 minut

Počet videí

8 videí + projekty

Certifikát

Po dokončení obdržíte certifikát


Lekce v této sekci


Struktura lekcí (souborový strom)

06. Typescript specifika
  • v přípravě
08. Moduly tridy
  • v přípravě
09. React zaklady
  • v přípravě
10. React hooks
  • v přípravě
12. Nextjs server
  • v přípravě
13. Databaze auth
  • v přípravě
14. Nextjs pokrocile
  • v přípravě