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

04.10 Sort

Výuka

Proč Sort?

sort() je metoda pro řazení prvků pole. Může seřadit čísla, texty, nebo objekty podle vlastního kritéria.

Proč to potřebujeme?

  • Uspořádání dat - Seřaď uživatele podle jména nebo věku
  • Hledání - Binární vyhledávání vyžaduje seřazené pole
  • Vizualizace - Zobraz data v přehledném pořadí
  • Analýza - Najdi minimální/maximální hodnoty snáze

Představ si to jako: Řazení knih na polici. Můžeš je řadit podle abecedy (jména), podle čísla (roku vydání), nebo podle tloušťky (počtu stran).

Jak to funguje?

sort():
1. BEZ compare funkce - řadí jako STRINGY (lexikograficky)!
   ['3', '10', '2']  ['10', '2', '3'] (!!!)
2. S compare funkcí - řadí podle vlastního kritéria
3. MUTUJE původní pole (mění ho na místě!)
4. Vrací seřazené pole (stejné jako originál)

Compare funkce (a, b):
Vrať ZÁPORNÉ číslo  a před b
Vrať KLADNÉ číslo  b před a
Vrať 0  pořadí se nemění

Klíčové koncepty

  • sort(compareFn?) - seřadí pole
  • MUTUJE pole - mění původní pole (na rozdíl od slice, filter)
  • Bez compare funkce - převádí na stringy a řadí lexikograficky (ASCII)
  • Compare funkce - (a, b) => number určuje pořadí
  • Stabilní řazení - prvky se stejnou hodnotou zůstávají v původním pořadí (od ES2019)
  • In-place sorting - řadí na místě, ne vytváří novou kopii

JavaScript

Příklad 1: Základní sort - texty (funguje)

const fruits = ['třešeň', 'banán', 'jablko', 'datle'];

fruits.sort();
console.log(fruits);
// → ['banán', 'datle', 'jablko', 'třešeň'] (abecedně)

// Originál SE ZMĚNIL (mutace!)
console.log(fruits);
// → ['banán', 'datle', 'jablko', 'třešeň']

Co se stalo?

  • Bez compare funkce - řadí jako stringy (lexikograficky)
  • Pro texty to funguje správně
  • MUTUJE původní pole (změna na místě!)

Příklad 2: Základní sort - čísla (NEFUNGUJE!)

const numbers = [3, 10, 2, 25, 1];

numbers.sort();
console.log(numbers);
// → [1, 10, 2, 25, 3] (ŠPATNĚ! Řadí jako stringy!)

// Proč? Porovnává '10', '2', '25', '3' → '1' < '10' < '2' < '25' < '3'

Co se stalo?

  • Bez compare funkce - převede čísla na stringy
  • Porovnává '10' vs '2''1' < '2' → 10 před 2 (ŠPATNĚ!)
  • Pro čísla MUSÍŠ použít compare funkci!

Příklad 3: sort() s compare funkcí - čísla (funguje)

const numbers = [3, 10, 2, 25, 1];

// Vzestupně (ascending)
numbers.sort(function(a, b) {
  return a - b;  // Záporné → a před b, Kladné → b před a
});
console.log(numbers);
// → [1, 2, 3, 10, 25] (SPRÁVNĚ!)

// Sestupně (descending)
const numbers2 = [3, 10, 2, 25, 1];
numbers2.sort((a, b) => b - a);
console.log(numbers2);
// → [25, 10, 3, 2, 1]

Co se stalo?

  • Compare funkce: (a, b) => a - b
    • a - b < 0 → a je menší → a před b
    • a - b > 0 → b je menší → b před a
    • a - b === 0 → stejné → pořadí se nemění
  • Vzestupně: a - b
  • Sestupně: b - a

Příklad 4: sort() objektů podle vlastnosti

const users = [
  { name: 'Charlie', age: 35 },
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 }
];

// Seřaď podle věku (vzestupně)
users.sort((a, b) => a.age - b.age);
console.log(users);
// → [
//   { name: 'Alice', age: 25 },
//   { name: 'Bob', age: 30 },
//   { name: 'Charlie', age: 35 }
// ]

// Seřaď podle jména (abecedně)
users.sort((a, b) => a.name.localeCompare(b.name));
console.log(users);
// → [
//   { name: 'Alice', age: 25 },
//   { name: 'Bob', age: 30 },
//   { name: 'Charlie', age: 35 }
// ]

Co se stalo?

  • Můžeš řadit objekty podle libovolné vlastnosti
  • Pro čísla: a.age - b.age
  • Pro stringy: a.name.localeCompare(b.name) (správné pro diakritiku!)

Příklad 5: localeCompare pro správné řazení textů

const words = ['žába', 'auto', 'čaj', 'pes'];

// Špatně - ASCII pořadí (nezohledňuje diakritiku)
const bad = words.slice().sort();
console.log(bad);
// → ['auto', 'pes', 'čaj', 'žába'] (špatně - č a ž na konci!)

// Správně - localeCompare (zohledňuje češtinu)
const good = words.slice().sort((a, b) => a.localeCompare(b, 'cs'));
console.log(good);
// → ['auto', 'čaj', 'pes', 'žába'] (správně!)

Co se stalo?

  • localeCompare() - správné řazení pro češtinu (a jiné jazyky)
  • Zohledňuje diakritiku (č, ř, š, ž, ...)
  • Druhý parametr je locale ('cs' pro češtinu)

Příklad 6: Immutabilní sort - neměň originál

const numbers = [3, 1, 4, 1, 5];

// ❌ Mutuje originál
const sorted1 = numbers.sort((a, b) => a - b);
console.log(numbers);  // → [1, 1, 3, 4, 5] (změněno!)

// ✅ Neměň originál - udělej kopii
const numbers2 = [3, 1, 4, 1, 5];
const sorted2 = numbers2.slice().sort((a, b) => a - b);
console.log(numbers2);  // → [3, 1, 4, 1, 5] (nezměněno!)
console.log(sorted2);   // → [1, 1, 3, 4, 5]

// ✅ Alternativa - spread operátor
const sorted3 = [...numbers2].sort((a, b) => a - b);

// ✅ Moderní (ES2023) - toSorted (neměnný)
const sorted4 = numbers2.toSorted((a, b) => a - b);  // Nová metoda!

Co se stalo?

  • sort() mutuje originál - nebezpečné v React/Redux!
  • Řešení: Udělej kopii pomocí slice() nebo [...]
  • ES2023: toSorted() - nová immutabilní verze sort()

TypeScript

TypeScript přidává typovou kontrolu compare funkce.

Stejné příklady s typy

// Sort čísel s typy
const numbers: number[] = [3, 10, 2, 25, 1];
numbers.sort((a: number, b: number): number => a - b);

// TypeScript inferuje typy
const sorted = numbers.sort((a, b) => a - b);  // a, b jsou number

// Sort objektů s interface
interface User {
  name: string;
  age: number;
}

const users: User[] = [
  { name: 'Charlie', age: 35 },
  { name: 'Alice', age: 25 }
];

// Podle věku
users.sort((a, b) => a.age - b.age);

// Podle jména
users.sort((a, b) => a.name.localeCompare(b.name, 'cs'));

// Chybová kontrola - compare funkce musí vracet number
const invalid = numbers.sort((a, b) => a > b);
// ⚠️ Funguje (boolean se převede na number), ale lépe explicitně number
const valid = numbers.sort((a, b) => a - b);  // ✅ Explicitně number

// Generická utility funkce
function sortBy<T>(arr: T[], fn: (item: T) => number | string): T[] {
  return arr.slice().sort((a, b) => {
    const aVal = fn(a);
    const bVal = fn(b);
    if (typeof aVal === 'number' && typeof bVal === 'number') {
      return aVal - bVal;
    }
    return String(aVal).localeCompare(String(bVal));
  });
}

const sortedByAge = sortBy(users, u => u.age);
const sortedByName = sortBy(users, u => u.name);

// Readonly pole - nelze použít sort (ale toSorted ano!)
const readonly: readonly number[] = [3, 1, 2];
// readonly.sort();  // ❌ Error: Property 'sort' does not exist on type 'readonly number[]'
const sorted = [...readonly].sort((a, b) => a - b);  // ✅ OK - kopie

TypeScript přidává:

  • Inference typů - TypeScript pozná typ prvků automaticky
  • Typovou kontrolu compare funkce - musí vracet number
  • Readonly kontrolu - readonly pole nepodporuje sort (mutující!)
  • Prevenci chyb - chyby odhalíš při psaní

Rozdíl JS vs TS

JavaScript:

  • sort funguje bez typové kontroly
  • Můžeš omylem vrátit špatný typ z compare funkce
  • Žádná ochrana před mutacemi
  • Flexibilnější, ale nebezpečnější

TypeScript:

  • Compare funkce je typově kontrolovaná
  • readonly pole brání použití sort
  • Lépe dokumentované záměry
  • Bezpečnější, prevence chyb
// JavaScript - projde, ale matoucí
const numbers = [3, 1, 2];
numbers.sort((a, b) => a > b);  // Vrací boolean, ne number (funguje, ale matoucí)

// TypeScript - funguje, ale lépe explicitně
const numbers: number[] = [3, 1, 2];
numbers.sort((a, b) => a - b);  // Jasný záměr - vrací number

Tip

💡 VŽDY používej compare funkci pro čísla:

// ❌ ŠPATNĚ - řadí jako stringy
[10, 2, 25, 3].sort();  // → [10, 2, 25, 3]

// ✅ SPRÁVNĚ - compare funkce
[10, 2, 25, 3].sort((a, b) => a - b);  // → [2, 3, 10, 25]

💡 Pro immutabilitu udělej kopii:

// ❌ Mutuje originál
const sorted = arr.sort();

// ✅ Neměň originál
const sorted = arr.slice().sort();
const sorted = [...arr].sort();
const sorted = arr.toSorted();  // ES2023+

💡 Pro texty s diakritikou použij localeCompare:

// ❌ Špatně - nezohledňuje češtinu
['žába', 'auto'].sort();  // → ['auto', 'žába'] (špatně - ž na konci!)

// ✅ Správně - localeCompare
['žába', 'auto'].sort((a, b) => a.localeCompare(b, 'cs'));  // → ['auto', 'žába']

Kvíz

Co vypíše tento kód?

const arr = [1, 5, 2, 10, 3];
arr.sort();
console.log(arr[0]);

- BEZ compare funkce sort() řadí jako stringy. Převede [1, 5, 2, 10, 3] na ['1', '5', '2', '10', '3'] a seřadí lexikograficky → ['1', '10', '2', '3', '5']. První prvek je '1'1

- '10' je až druhý v lexikografickém pořadí

- '2' je až třetí

- Kód je validní

Důležité: NIKDY nepoužívej sort() bez compare funkce pro čísla! Výsledek bude špatně!

Důležité: NIKDY nepoužívej sort() bez compare funkce pro čísla! Výsledek bude špatně!

🎯 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ě