04.06 Filter
Výuka
Proč Filter?
filter() je metoda, která filtruje prvky pole podle podmínky a vytvoří nové pole jen s prvky, které podmínku splnily.
Proč to potřebujeme?
- Výběr dat - Vyber jen prvky, které splňují kritérium (sudá čísla, aktivní uživatelé)
- Filtrování - Odstraň nechtěné prvky (null hodnoty, duplicity)
- Immutability - Vytvoř nové pole, nezměň originál (bezpečné pro React state)
- Čitelnost - Místo smyčky s podmínkou použiješ deklarativní filtr
Představ si to jako: Cedník na těstoviny. Dáš dovnitř směs těstovin a vody, cedník propustí jen těstoviny (splňují podmínku "je pevné"). Voda (nesplňuje) odteče pryč.
Jak to funguje?
1. filter(fn) - zavolá funkci fn pro každý prvek pole
2. Funkce fn vrací true (prvek projde) nebo false (prvek se zahodí)
3. Vytvoří NOVÉ pole jen s prvky, kde fn vrátila true
4. NEMĚNÍ původní pole (immutabilní)
5. Výsledné pole může být KRATŠÍ než originál (nebo i prázdné)
Klíčové koncepty
filter(predicate)- filtruje prvky podle podmínky, vrací nové pole- Predicate - funkce vracející
truenebofalse:(element, index, array) => boolean - Immutability -
filter()NEMĚNÍ originál - Nový počet prvků - výsledek může mít méně prvků (nebo 0)
- Pure function - predikát by neměl mít vedlejší efekty
- Chainable - můžeš řetězit:
arr.filter(...).map(...)
JavaScript
Příklad 1: Základní filtrování - sudá čísla
const numbers = [1, 2, 3, 4, 5, 6];
const even = numbers.filter(function(num) {
return num % 2 === 0;
});
console.log(even);
// → [2, 4, 6]
console.log(numbers);
// → [1, 2, 3, 4, 5, 6] (originál NEZMĚNĚN)
Co se stalo?
filter()zavolá funkci pro každý prvek- Funkce vrací
truepro sudá čísla (num % 2 === 0) - Pouze prvky, kde funkce vrátila
true, se dostanou do nového pole - Původní pole zůstává netknuté
Příklad 2: Arrow funkce (kratší syntax)
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Sudá čísla
const even = numbers.filter(n => n % 2 === 0);
console.log(even);
// → [2, 4, 6, 8, 10]
// Čísla větší než 5
const greaterThan5 = numbers.filter(n => n > 5);
console.log(greaterThan5);
// → [6, 7, 8, 9, 10]
// Násobky 3
const multiplesOf3 = numbers.filter(n => n % 3 === 0);
console.log(multiplesOf3);
// → [3, 6, 9]
Co se stalo?
n => n % 2 === 0je arrow funkce s implicitním return- Stručnější a čitelnější
- Každý filter vytvoří nové pole
Příklad 3: Filtrování objektů
const users = [
{ name: 'Alice', age: 25, active: true },
{ name: 'Bob', age: 17, active: false },
{ name: 'Charlie', age: 30, active: true },
{ name: 'David', age: 16, active: true }
];
// Jen dospělí (18+)
const adults = users.filter(user => user.age >= 18);
console.log(adults);
// → [
// { name: 'Alice', age: 25, active: true },
// { name: 'Charlie', age: 30, active: true }
// ]
// Jen aktivní uživatelé
const activeUsers = users.filter(user => user.active);
console.log(activeUsers);
// → [
// { name: 'Alice', age: 25, active: true },
// { name: 'Charlie', age: 30, active: true },
// { name: 'David', age: 16, active: true }
// ]
// Kombinace podmínek
const activeAdults = users.filter(user => user.active && user.age >= 18);
console.log(activeAdults);
// → [
// { name: 'Alice', age: 25, active: true },
// { name: 'Charlie', age: 30, active: true }
// ]
Co se stalo?
- Můžeš filtrovat objekty podle libovolné vlastnosti
user.activeje zkratka prouser.active === true- Můžeš kombinovat podmínky pomocí
&&(a) nebo||(nebo)
Příklad 4: filter s indexem
const letters = ['a', 'b', 'c', 'd', 'e'];
// Jen prvky na sudých indexech (0, 2, 4)
const evenIndexes = letters.filter((letter, index) => index % 2 === 0);
console.log(evenIndexes);
// → ['a', 'c', 'e']
// Jen prvky po indexu 2
const afterIndex2 = letters.filter((letter, index) => index > 2);
console.log(afterIndex2);
// → ['d', 'e']
Co se stalo?
- Predikát má 3 parametry:
element- aktuální prvekindex- index prvkuarray- celé pole (zřídka se používá)
- Můžeš filtrovat podle indexu, ne jen podle hodnoty
Příklad 5: Odstranění falsy hodnot (compact)
const mixed = [0, 1, false, 2, '', 3, null, 4, undefined, 5, NaN];
// Odstraň všechny falsy hodnoty
const truthy = mixed.filter(Boolean);
console.log(truthy);
// → [1, 2, 3, 4, 5]
// Alternativa - explicitní
const truthy2 = mixed.filter(x => x);
console.log(truthy2);
// → [1, 2, 3, 4, 5]
Co se stalo?
filter(Boolean)- použij vestavěnou funkciBooleanjako predikátBoolean(0)=false,Boolean(1)=true- Odstraní všechny falsy hodnoty:
false,0,'',null,undefined,NaN - Pozor: Odstraní i platné hodnoty jako
0nebo''!
Příklad 6: Kombinace filter a map (řetězení)
const numbers = [1, 2, 3, 4, 5, 6];
// Vezmi sudá čísla a vynásob je dvěma
const result = numbers
.filter(n => n % 2 === 0) // [2, 4, 6]
.map(n => n * 2); // [4, 8, 12]
console.log(result);
// → [4, 8, 12]
// Nebo v opačném pořadí
const result2 = numbers
.map(n => n * 2) // [2, 4, 6, 8, 10, 12]
.filter(n => n > 5); // [6, 8, 10, 12]
console.log(result2);
// → [6, 8, 10, 12]
Co se stalo?
- Můžeš řetězit
filteramap - Pořadí záleží - může ovlivnit výsledek i výkon
- Optimalizace: Filtruj před map, pokud můžeš (méně prvků k transformaci)
TypeScript
TypeScript přidává typovou kontrolu predikátu a type guards pro zúžení typů.
Stejné příklady s typy
// Základní filtrování s typy
const numbers: number[] = [1, 2, 3, 4, 5, 6];
const even: number[] = numbers.filter((n: number): boolean => n % 2 === 0);
// TypeScript inferuje typy
const greaterThan5 = numbers.filter(n => n > 5); // number[]
// Filtrování objektů s interface
interface User {
name: string;
age: number;
active: boolean;
}
const users: User[] = [
{ name: 'Alice', age: 25, active: true },
{ name: 'Bob', age: 17, active: false }
];
const adults: User[] = users.filter(user => user.age >= 18);
// Type guard - zúžení typu
const mixed: (string | number | null)[] = [1, 'a', null, 2, 'b', null];
// Odstraň null hodnoty a zúž typ
const notNull: (string | number)[] = mixed.filter((x): x is string | number => x !== null);
// Type predicate - vlastní type guard
function isString(x: any): x is string {
return typeof x === 'string';
}
const strings: string[] = mixed.filter(isString); // jen stringy
// Chybová kontrola - predikát musí vracet boolean
const invalid = numbers.filter(n => n); // ⚠️ Funguje, ale vrací number (truthy), ne boolean
const valid = numbers.filter(n => n > 0); // ✅ Explicitně boolean
// Readonly pole
const readonly: readonly number[] = [1, 2, 3, 4, 5];
const filtered: number[] = readonly.filter(n => n > 2); // ✅ OK - filter je immutabilní
TypeScript přidává:
- ✅ Inference typů - TypeScript pozná typ prvku automaticky
- ✅ Type guards -
x is Tzúží typ ve výsledném poli - ✅ Typovou kontrolu predikátu - musí vracet boolean (nebo truthy hodnotu)
- ✅ IntelliSense - editor ti napovídá vlastnosti objektů
- ✅ Prevenci chyb - chyby odhalíš při psaní
Rozdíl JS vs TS
JavaScript:
- filter funguje bez typové kontroly
- Nemáš type guards - typ se nezúží
- Predikát může vracet cokoliv (truthy/falsy)
- Flexibilnější, ale nebezpečnější
TypeScript:
- Predikát je typově kontrolovaný
- Type guards zužují typ ve výsledném poli
- Lépe dokumentované záměry
- Bezpečnější, prevence chyb
// JavaScript - typ se nezúží
const mixed = [1, 'a', null, 2];
const notNull = mixed.filter(x => x !== null); // stále (number | string | null)[]
// TypeScript s type guard - typ se zúží
const mixed: (number | string | null)[] = [1, 'a', null, 2];
const notNull: (number | string)[] = mixed.filter((x): x is number | string => x !== null);
Tip
💡 filter + map vs kombinovaná operace:
// ✅ Čitelné - oddělené fáze
const result = numbers
.filter(n => n > 5)
.map(n => n * 2);
// ⚠️ Méně čitelné, ale rychlejší (jen jedna iterace)
const result = numbers.reduce((acc, n) => {
if (n > 5) acc.push(n * 2);
return acc;
}, []);
// Pro většinu případů preferuj filter + map (čitelnější)
💡 Filtruj PŘED map pro lepší výkon:
// ✅ Efektivnější - méně prvků k transformaci
const result = numbers
.filter(n => n > 10) // Zmenší pole
.map(expensiveOp); // Méně volání
// ❌ Neefektivní - transformuje všechny, pak filtruje
const result = numbers
.map(expensiveOp) // Mnoho volání
.filter(n => n > 10); // Filtruje až pak
💡 Odstraň duplicity pomocí filter:
const arr = [1, 2, 2, 3, 3, 3, 4];
// Ponechej jen první výskyt každé hodnoty
const unique = arr.filter((value, index, self) => self.indexOf(value) === index);
console.log(unique);
// → [1, 2, 3, 4]
// Moderní způsob - použij Set
const unique2 = [...new Set(arr)]; // Rychlejší
Kvíz
Co vypíše tento kód?
const arr = [0, 1, 2, 3, 4, 5];
const result = arr.filter(x => x);
console.log(result);
❌ - 0 je falsy hodnota
✅ - Predikát x => x vrací hodnotu x samotnou. filter ponechá jen truthy hodnoty. 0 je falsy, takže se odstraní. Všechny ostatní čísla (1, 2, 3, 4, 5) jsou truthy, takže projdou
❌ - Nejsou odstraněny všechny hodnoty
❌ - 0 je falsy, takže se odstraní
Důležité: Predikát může vracet libovolnou hodnotu, která se převede na boolean. 0 → false, 1 → true. Lepší je explicitně psát x => x !== 0 nebo x => x > 0.
Důležité: Predikát může vracet libovolnou hodnotu, která se převede na boolean. 0 → false, 1 → true. Lepší je explicitně psát x => x !== 0 nebo x => x > 0.
🎯 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 →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
- 04.01 Vytvoření pole
- 04.02 Přístup k prvkům
- 04.03 Push, pop, shift, unshift
- 04.04 Slice a splice
- 04.06 Filter
- 04.07 Reduce
- 04.08 Find a findIndex
- 04.09 Some a every
- 04.10 Sort
- 04.11 Spread operátor
- 04.12 Set
- 04.13 Map kolekce
- 04.14 Destructuring polí
Struktura lekcí (souborový strom)
- 1.1 Úvod do JavaScriptu a TypeScriptu
- 1.2 Nastavení prostředí
- 1.3 První program
- 1.4 Proměnné: var, let, const
- 1.5 Datové typy - přehled
- 1.6 String (řetězce)
- 1.7 Number (čísla)
- 1.8 Boolean (pravda/nepravda)
- 1.9 Null a Undefined
- 1.10 Type Inference vs Annotations
- 1.11 Aritmetické operátory
- 1.12 Porovnávací operátory
- 1.13 Logické operátory
- 1.14 Komentáře
- 1.15 Console metody
- 03.01 Deklarace funkce
- 03.02 Function Expression
- 03.03 Arrow Functions
- 03.04 Parametry a argumenty
- 03.05 Return hodnoty
- 03.06 Výchozí parametry
- 03.07 Rest parametry
- 03.08 Co je Scope
- 03.09 Lexikální Scope
- 03.10 Řetězec Scope
- 03.11 Globální Scope
- 03.12 Životní Cyklus Proměnných
- 03.13 Omezení Scope
- 03.14 Použití Closures
- 03.15 Callback funkce
- 03.16 Higher-order Functions
- 03.17 IIFE
- 03.18 Void funkce
- 03.19 Rekurze
- v přípravě
- v přípravě
- v přípravě
- v přípravě
- 01 — Co je Next.js
- 02 — Vytvoření projektu
- 03 — Struktura projektu (app/)
- 04 — Page komponenty (page.js / page.tsx)
- 05 — Layout komponenty (layout.js / layout.tsx)
- 06 — File-based routing
- 07 — Dynamické routy ([id]/page.js)
- 08 — Link komponenta (navigace)
- 09 — Image komponenta (next/image)
- 10 — Metadata (title, description, Open Graph)
- 11 — Loading UI (loading.js / loading.tsx)
- 12 — Error handling (error.js / error.tsx)
- 13 — Not Found (not-found.js / not-found.tsx)
- v přípravě
- v přípravě
- v přípravě