Funkce v map a filter

Pole mají metody, které dostávají jako argument funkci. Dvě z nich se používají pořád a jsou pro vás nové: map a filter. Obě patří do obyčejného JavaScriptu, TypeScript k nim přidává jednu užitečnou věc.

map vytvoří nové pole. Pro každý prvek zavolá vaši funkci a to, co funkce vrátí, uloží do nového pole, ve stejném pořadí:

const truhly = [10, 25, 40];
const dvojnasobek = truhly.map(zlato => zlato * 2);

console.log(dvojnasobek);
console.log(truhly);

Vypíše:

[20, 50, 80]
[10, 25, 40]

map zavolala zlato => zlato * 2 třikrát, s hodnotami 10, 25 a 40, a posbírala výsledky. Původní pole truhly se nezměnilo. Dělá totéž co tento cyklus, jen na jednom řádku:

const dvojnasobek: number[] = [];
for (const zlato of truhly) {
    dvojnasobek.push(zlato * 2);
}

Funkce může vracet hodnotu jiného typu. Nové pole pak má prvky tohoto typu:

const jmena = ["Kira", "Bruno", "Lena"];
console.log(jmena.map(jmeno => jmeno.toUpperCase()));
console.log(jmena.map(jmeno => jmeno.length));

Vypíše:

["KIRA", "BRUNO", "LENA"]
[4, 5, 4]

Všimněte si, že zlato ani jmeno nemají typ, a TypeScriptu to nevadí. To je ta užitečná věc: TypeScript ví, že truhly je number[], takže funkce předaná metodě map dostane čísla a zlato je number. Parametr dostane typ podle místa, kde je funkce napsaná (anglicky se tomu říká contextual typing). TypeScript ví i to, co map vrátí: zlato * 2 je číslo, a tak vznikne pole čísel, number[]. A protože ví, že jmeno je text, kontroluje, co s ním děláte:

const jmena = ["Kira", "Bruno", "Lena"];
const dvojnasobek = jmena.map(jmeno => jmeno * 2);
main.ts(2,40): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Hláška říká, že levá strana aritmetické operace musí být číslo. Funguje to jen tehdy, když funkci napíšete přímo tam, kde se použije, tedy jako argument. Šipková funkce uložená samostatně v proměnné bez typu potřebuje typy parametrů dál, protože TypeScript neví, kde se použije:

const zdvojnasob = zlato => zlato * 2;
main.ts(1,20): error TS7006: Parameter 'zlato' implicitly has an 'any' type.

filter také vytvoří nové pole, ale nechá v něm jen některé prvky: ty, pro které vaše funkce vrátí true:

const prisery = [
    { jmeno: "skřet", sila: 4 },
    { jmeno: "troll", sila: 15 },
    { jmeno: "vlk", sila: 8 },
    { jmeno: "drak", sila: 40 },
];
const silne = prisery.filter(prisera => prisera.sila > 10);

console.log(silne);
console.log(silne.map(prisera => prisera.jmeno));

Vypíše:

[{ jmeno: "troll", sila: 15 }, { jmeno: "drak", sila: 40 }]
["troll", "drak"]

Tady dostane prisera typ prvků pole, { jmeno: string; sila: number; }, a tak TypeScript odhalí překlep:

const prisery = [
    { jmeno: "skřet", sila: 4 },
    { jmeno: "troll", sila: 15 },
    { jmeno: "vlk", sila: 8 },
    { jmeno: "drak", sila: 40 },
];
const silne = prisery.filter(prisera => prisera.silla > 10);
main.ts(7,49): error TS2551: Property 'silla' does not exist on type '{ jmeno: string; sila: number; }'. Did you mean 'sila'?

Výsledek metody filter má stejný typ jako původní pole, takže s ním můžete dál pracovat. Poslední řádek příkladu na výsledek zavolá map a získá jen jména.

Typické chyby:

  • Složené závorky bez return: truhly.map(zlato => { zlato * 2 }) dá [undefined, undefined, undefined] a stejná chyba ve filter dá []. TypeScript to tady neohlásí, a tak když použijete složené závorky, napište return.
  • Čekat, že map nebo filter pole změní. Nezmění, vracejí nové pole. Uložte ho do proměnné, nebo ho rovnou použijte.

Pokyny

Šťastný den: zlato v každé truhle se zdvojnásobí. Zavolejte map na truhly a vytvořte tak pole dvojnasobneZlato s dvojnásobkem zlata z každé truhly.

Vypište dvojnasobneZlato a pak truhly, abyste viděli, že map původní pole nezměnila. Program vypíše:

[24, 60, 14, 90]
[12, 30, 7, 45]

Kira bojuje jen se silnými příšerami, tedy s těmi, jejichž síla je větší než 10. Zavolejte filter na prisery a vytvořte tak pole silnePrisery, ve kterém budou jen ony.

Vypište silnePrisery a pak jen jména silných příšer: zavolejte map na silnePrisery. Program na konci vypíše:

[{ jmeno: "troll", sila: 25 }, { jmeno: "kostlivec", sila: 12 }]
["troll", "kostlivec"]

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

9/10