HALLOWEEN JE TADY: Získej 66 % extra kreditů zdarma při nákupu od 1199 kreditů s promo kódem NEBOJSEIT66. Zjisti více:
NOVINKA: Začni v IT jako webmaster s komplexním akreditovaným online kurzem Tvůrce WWW stránek. Zjisti více:

Lekce 11 - Pole v JavaScriptu podruhé - Řazení prvků a 2D pole

V minulé lekci, Pole v JavaScriptu, jsme se naučili používat pole. Ukázali jsme si práci s prvky pole.

V tutoriálu základů JavaScriptu se budeme věnovat další práci s polem. Ukážeme si, jak prvky pole seřadit. Představíme si také pole polí, tedy dvojrozměrné pole. Využijeme jej při tvorbě aplikace, která bude mít za úkol zjistit, kdo má daný den v roce svátek.

Řazení prvků v poli

Položky v poli lze jednoduše seřadit metodou sort().

Řazení textu

Pokud jsou v poli textové řetězce, metoda sort() nám je seřadí podle abecedy (vzestupně):

let jmena = ["Dan", "Bohouš", "Cyril", "Anna"];
jmena.sort();
for (let jmeno of jmena) {
    document.body.innerHTML += jmeno + " ";
}

Kód výše vytvoří pole se 4 textovými řetězci. Následně jeho položky seřadí podle abecedy. Nakonec všechny prvky pole vypíše cyklem for.

Výstup v prohlížeči:

Pole v JavaScriptu
localhost

Vidíme, že se jména v poli seřadila podle abecedy.

Obrácené pořadí a sestupné řazení

Pořadí prvků v poli můžeme otočit pomocí metody reverse(). Tak bude první prvek jako poslední, druhý jako předposlední atd. Přidejme otočení prvků pole do našeho příkladu. Jelikož máme pole seřazené, bude výsledkem otočení pole seřazené od Z do A, tedy sestupně. Do předchozího příkladu tedy přidáme volání této metody před cyklus pro výpis prvků pole:

let jmena = ["Dan", "Bohouš", "Cyril", "Anna"];
jmena.sort();
jmena.reverse(); // Přidaný řádek
for (let jmeno of jmena) {
    document.body.innerHTML += jmeno + " ";
}

Výstup v prohlížeči:

Pole v JavaScriptu
localhost

Řazení čísel

Pokud máme v poli čísla, asi byste čekali, že je metoda sort() seřadí od nejnižšího po nejvyšší. To se ale nestane.

Pozor! JavaScript prvky pole řadí vždy jako texty, i když jsou to čísla! To znamená, že 11 je dříve než 2, protože znak "1" je před znakem "2"

Vyzkoušejme si to:

let cisla = [5, 3, 30, 25];
cisla.sort();
for (let cislo of cisla) {
    document.body.innerHTML += cislo + " ";
}

Výstup:

Pole v JavaScriptu
localhost

Vidíme, že metoda sort() čísla opravdu neseřadí jako čísla.

Parametr metody sort()

Abychom docílili správného výsledku, musíme metodě sort() předat parametr, jak má prvky pole porovnávat. Parametrem předáme funkci, ve které od sebe vždy dva porovnávané prvky pole odečteme. Tím vznikne buď kladný nebo záporný výsledek (podle toho, zda je číslo větší nebo menší než to druhé) a na jeho základě si už sort() prvek správně zařadí:

let cisla = [5, 3, 30, 25];
cisla.sort(function(a, b) { return a - b });
for (let cislo of cisla) {
    document.body.innerHTML += cislo + " ";
}

V prohlížeči si můžeme ověřit, že jsou čísla již seřazena správně jako čísla:

Pole v JavaScriptu
localhost

Pokud vás funkce zmátla, vůbec to nevadí. Budeme se jim podrobně věnovat v lekci Funkce v JavaScriptu se spoustou dalších příkladů a zde je zmíněná jen proto, aby byly informace o poli hezky u sebe. Zápis funkcí a vše o nich si tedy ještě podrobně ukážeme.

Dvourozměrné pole v JavaScriptu

Mnohé z nás asi nepřekvapí, že JavaScript umožňuje vytvořit také pole, které obsahuje další pole jako své prvky. Hovoříme pak o poli polí nebo o dvojrozměrném poli.

Dvourozměrné pole si můžeme v paměti představit jako tabulku a mohli bychom takto reprezentovat např. rozehranou partii piškvorek. Pokud bychom se chtěli držet reálných aplikací, můžeme si představit, že do 2D pole budeme ukládat informace o obsazenostech sedadel v kinosálu. Situaci bychom si mohli graficky znázornit např. takto:

Struktura dvourozměrného pole v JavaScriptu - Základní konstrukce jazyka JavaScript

(Na obrázku je vidět 2D pole reprezentující obsazenost kinosálu)

Kinosál by byl v praxi samozřejmě větší, ale jako ukázka nám toto pole postačí. 0 znamená volno, 1 obsazeno. Později bychom mohli doplnit i 2 pro rezervováno a podobně.

Vícerozměrná pole využijeme zejména, pokud programujeme nějakou simulaci, například hru.

Deklarace 2D pole

Dvojrozměrné pole je možné deklarovat a naplnit daty takto:

let kinosal = [
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 1, 1, 1, 0],
    [1, 1, 1, 1, 1]
];

Proměnná kinosal je pole, které obsahuje jako své prvky několik dalších polí, představující jednotlivé řádky výsledného 2D pole.

Přístup k prvkům 2D pole

Pokud bychom nyní chtěli např. nastavit prvek úplně vlevo nahoře na hodnotu 1, musíme uvést dvě hranaté závorky a v nich index řádku a index sloupce. První řádek i sloupec mají indexy 0:

kinosal[0][0] = 1;

Tento řádek nemusíme zanášet do výsledného programu.

Vytvoření 2D pole programově

Když by bylo 2D pole větší nebo jsme předem nevěděli jeho velikost, je výhodnější jej vytvořit programově pomocí cyklů.

Vytvoření prázdného 2D pole pomocí cyklů

Prvně si vytvoříme prázdné pole:

let kinosal = [];

Následně na jeho indexech vytvoříme několik nových polí, pro každý řádek jedno:

for (let i = 0; i < 5; i++) {
    kinosal[i] = []; // Přidání řádku
}

Zbývá jen vnitřní pole, která představují řádky, naplnit nulami. To uděláme dalším vnořeným cyklem. Celý kód pak vypadá takto:

let kinosal = [];
for (let i = 0; i < 5; i++) {
    kinosal[i] = []; // Přidání řádku

    for (let j = 0; j < 5; j++) {
        kinosal[i][j] = 0; // Naplnění řádku nulami
    }
}

První cyklus udává index řádku, druhý vnořený cyklus udává index prvku v řádku (samozřejmě si cykly můžeme i otočit a souřadnice by potom byly prohozené, např. u grafických aplikací je zvykem prvně zadávat index sloupce a až potom řádku).

Naplnění 2D pole daty

Nyní kinosál naplníme jedničkami tak, jak je vidět na obrázku:

Struktura dvourozměrného pole v JavaScriptu - Základní konstrukce jazyka JavaScript

Pro přístup k prvku 2D pole musíme zadat dvě souřadnice pomocí indexů. Prostřední prvek našeho kinosálu je tedy na pozici kinosal[2][2]. Za předešlý kód přidáme:

kinosal[2][2] = 1; // Prostřední jednička

// Úprava 4. řádku
for (let i = 1; i < 4; i++) {
    kinosal[3][i] = 1;
}

// Naplnění celého posledního řádku
for (let i = 0; i < 5; i++) {
    kinosal[4][i] = 1;
}

Výpis 2D pole

Výpis pole do stránky provedeme pomocí cyklu. Budeme potřebovat dva cykly (jeden nám proiteruje řádky a druhý sloupce). Je to stejný princip, jako když jsme vypisovali dvěma vnořenými cykly malou násobilku. Jako správní programátoři nevložíme počet řádků a sloupců do cyklů napevno, jelikož se může změnit.

Musíme však pamatovat na skutečnost, že když se zeptáme na kinosal.length, bude obsahovat počet vnořených polí (řádků). Abychom získali počet sloupců (délku vnitřního pole), zeptáme se na kinosal[i].length.

Cykly zanoříme do sebe tak, aby nám vnější cyklus projížděl řádky a vnitřní sloupce v aktuálním řádku. Pro výpis využijeme HTML tabulku. Oba cykly musí mít samozřejmě jinou řídící proměnnou. Doplníme tedy tento kód:

let tabulka = "<table border='1'>";

for (let i = 0; i < kinosal.length; i++) {
    tabulka += "<tr>";
    for (let j = 0; j < kinosal[i].length; j++) {
        tabulka += "<td>" + kinosal[i][j] + "</td>";
    }
    tabulka += "</tr>";
}

tabulka += "</table>";
document.body.innerHTML += tabulka;

Když nyní spustíme celý příklad v prohlížeči, dostaneme tento výstup:

2D pole v JavaScriptu
localhost

Příklad – Výpis svátků pro daný den

Na závěr si vytvoříme skript vypisující, kdo má dnes svátek. Veřte nebo ne, použijeme k tomu právě 2D pole. To bude mít 12 řádků jako měsíců a v každém řádku budou za sebou uložena jména svátků v daném měsíci.

Příprava dat

Nejprve si vytvoříme prázdné vnější pole řádků (měsíců). Každý měsíc pak přidáme metodou push() jako pole již naplněné jmény. Postupně takto doplníme položky se všemi jmény v roce:

// Tento skript pochází z webu itnetwork.cz
// Smí být libovolně používán i modifikován, ale nesmí z něj být umazán tento text

// vytvoříme si prázdné pole měsíců a postupně do něj přidáme pole se svátky v daném měsíci
let mesice = [];

// leden
mesice.push(["Nový rok, Den obnovy samostatného českého státu", "Karina", "Radmila", "Diana", "Dalimil", "Tři králové", "Vilma", "Čestmír", "Vladan", "Břetislav", "Bohdana", "Pravoslav", "Edita", "Radovan", "Alice", "Ctirad", "Drahoslav", "Vladislav", "Doubravka", "Ilona", "Běla", "Slavomír", "Zdeněk", "Milena", "Miloš", "Zora", "Ingrid", "Otýlie", "Zdislava", "Robin", "Marika"]);
// únor
mesice.push(["Hynek", "Nela", "Blažej", "Jarmila", "Dobromila", "Vanda", "Veronika", "Milada", "Apolena", "Mojmír", "Božena", "Slavěna", "Věnceslav", "Valentýn", "Jiřina", "Ljuba", "Miloslava", "Gizela", "Patrik", "Oldřich", "Lenka", "Petr", "Svatopluk", "Matěj", "Liliana", "Dorota", "Alexandr", "Lumír", "Horymír"]);
// březen
mesice.push(["Bedřich", "Anežka", "Kamil", "Stela", "Kazimír", "Miroslav", "Tomáš", "Gabriela", "Františka", "Viktorie", "Anděla", "Řehoř", "Růžena", "Rút, Matylda", "Ida", "Elena, Herbert", "Vlastimil", "Eduard", "Josef", "Světlana", "Radek", "Leona", "Ivona", "Gabriel", "Marián", "Emanuel", "Dita", "Soňa", "Taťána", "Arnošt", "Kvido"]);
// duben
mesice.push(["Hugo", "Erika", "Richard", "Ivana", "Miroslava", "Vendula", "Heřman, Hermína", "Ema", "Dušan", "Darja", "Izabela", "Julius", "Aleš", "Vincenc", "Anastázie", "Irena", "Rudolf", "Valérie", "Rostislav", "Marcela", "Alexandra", "Evženie", "Vojtěch", "Jiří", "Marek", "Oto", "Jaroslav", "Vlastislav", "Robert", "Blahoslav"]);
// květen
mesice.push(["Svátek práce", "Zikmund", "Alexej", "Květoslav", "Klaudie", "Radoslav", "Stanislav", "Den vítězství", "Ctibor", "Blažena", "Svatava", "Pankrác", "Servác", "Bonifác", "Žofie", "Přemysl", "Aneta", "Nataša", "Ivo", "Zbyšek", "Monika", "Emil", "Vladimír", "Jana", "Viola", "Filip", "Valdemar", "Vilém", "Maxmilián", "Ferdinand", "Kamila"]);
// červen
mesice.push(["Laura", "Jarmil", "Tamara", "Dalibor", "Dobroslav", "Norbert", "Iveta, Slavoj", "Medard", "Stanislava", "Gita", "Bruno", "Antonie", "Antonín", "Roland", "Vít", "Zbyněk", "Adolf", "Milan", "Leoš", "Květa", "Alois", "Pavla", "Zdeňka", "Jan", "Ivan", "Adriana", "Ladislav", "Lubomír", "Petr a Pavel", "Šárka"]);
// červenec
mesice.push(["Jaroslava", "Patricie", "Radomír", "Prokop", "Cyril, Metoděj", "Den upálení mistra Jana Husa", "Bohuslava", "Nora", "Drahoslava", "Libuše, Amálie", "Olga", "Bořek", "Markéta", "Karolína", "Jindřich", "Luboš", "Martina", "Drahomíra", "Čeněk", "Ilja", "Vítězslav", "Magdaléna", "Libor", "Kristýna", "Jakub", "Anna", "Věroslav", "Viktor", "Marta", "Bořivoj", "Ignác"]);
// srpen
mesice.push(["Oskar", "Gustav", "Miluše", "Dominik", "Kristián", "Oldřiška", "Lada", "Soběslav", "Roman", "Vavřinec", "Zuzana", "Klára", "Alena", "Alan", "Hana", "Jáchym", "Petra", "Helena", "Ludvík", "Bernard", "Johana", "Bohuslav", "Sandra", "Bartoloměj", "Radim", "Luděk", "Otakar", "Augustýn", "Evelína", "Vladěna", "Pavlína"]);
// září
mesice.push(["Linda, Samuel", "Adéla", "Bronislav", "Jindřiška", "Boris", "Boleslav", "Regína", "Mariana", "Daniela", "Irma", "Denisa", "Marie", "Lubor", "Radka", "Jolana", "Ludmila", "Naděžda", "Kryštof", "Zita", "Oleg", "Matouš", "Darina", "Berta", "Jaromír", "Zlata", "Andrea", "Jonáš", "Václav, Den české státnosti", "Michal", "Jeroným"]);
// říjen
mesice.push(["Igor", "Olivie, Oliver", "Bohumil", "František", "Eliška", "Hanuš", "Justýna", "Věra", "Štefan, Sára", "Marina", "Andrej", "Marcel", "Renáta", "Agáta", "Tereza", "Havel", "Hedvika", "Lukáš", "Michaela", "Vendelín", "Brigita", "Sabina", "Teodor", "Nina", "Beáta", "Erik", "Šarlota, Zoe", "Den vzniku samostatného československého státu", "Silvie", "Tadeáš", "Štěpánka"]);
// listopad
mesice.push(["Felix", "Památka zesnulých (dušičky)", "Hubert", "Karel", "Miriam", "Liběna", "Saskie", "Bohumír", "Bohdan", "Evžen", "Martin", "Benedikt", "Tibor", "Sáva", "Leopold", "Otmar", "Mahulena, Den boje za svobodu a demokracii", "Romana", "Alžběta", "Nikola", "Albert", "Cecílie", "Klement", "Emílie", "Kateřina", "Artur", "Xenie", "René", "Zina", "Ondřej"]);
// prosinec
mesice.push(["Iva", "Blanka", "Svatoslav", "Barbora", "Jitka", "Mikuláš", "Benjamín", "Květoslava", "Vratislav", "Julie", "Dana", "Simona", "Lucie", "Lýdie", "Radana", "Albína", "Daniel", "Miloslav", "Ester", "Dagmar", "Natálie", "Šimon", "Vlasta", "Adam, Eva, Štědrý den", "1. svátek vánoční", "Štěpán, 2. svátek vánoční", "Žaneta", "Bohumila", "Judita", "David", "Silvestr"]);

Zjištění svátku

To nejtěžší máme za sebou! Nyní stačí zjistit jen:

  • Aktuální den pomocí metody getDate(). Metoda vrací hodnotu 131, pokud tedy chceme získat odpovídající index v poli pro aktuální den, musíme odečíst 1, protože indexy pole jsou od nuly.
  • Aktuální měsíc metodou getMonth(). Ta vrací hodnotu od 0 do 11, kde 0 odpovídá lednu a 11 prosinci, získanou hodnotu tedy již nemusíme upravovat.

Nakonec vybereme hledaný prvek v poli polí, použijeme tedy nejprve index měsíce a poté index dne:

// nyní přistoupíme k samotnému výpisu
let dnes = new Date();
let den = dnes.getDate()-1;
let mesic = dnes.getMonth();
document.body.innerHTML += "Dnes má svátek " + mesice[mesic][den];

Výsledek:

Pole v JavaScriptu
localhost

Gratuluji, nyní máte kromě ukázky použití pole i užitečný skript na svůj web 🏆

V následujícím cvičení, Řešené úlohy k 10.-11. lekci JavaScriptu, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 309x (4.47 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Pole v JavaScriptu
Všechny články v sekci
Základní konstrukce jazyka JavaScript
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 10.-11. lekci JavaScriptu
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
793 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity