Lekce 10 - 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
Tato metoda nám seřadí textové řetězce podle abecedy (vzestupně):
let jmena = ["Dan", "Bohouš", "Cyril", "Anna"]; jmena.sort(); for (let jmeno of jmena) { document.write(jmeno + " "); }
Výstup v prohlížeči:
Sestupné řazení
Pořadí prvků v poli můžeme otočit
pomocí metody reverse()
. Do předchozího příkladu tedy
přidáme volání této metody a cyklus pro výpis prvků pole:
jmena.reverse(); for (let jmeno of jmena) { document.write(jmeno + " "); }
Výstup v prohlížeči:
Řazení čísel
Pokud máme v poli čísla, metoda sort()
je
seřadí jako textové řetězce:
let cisla = [5, 3, 30, 25]; cisla.sort(); for (let cislo of cisla) { document.write(cislo + " "); }
Výstup:
Tento výpis je ale správně pouze lexikograficky, nikoliv tak, jak jsme měli v úmyslu. Abychom docílili správného výsledku, musíme metodě přidat anonymní funkci, v níž určíme, podle čeho má prvky našeho pole porovnat. Použijeme tedy následující zápis:
let cisla = [5, 3, 30, 25]; cisla.sort(function(a, b) { return a - b }); for (let cislo of cisla) { document.write(cislo + " "); }
V prohlížeči si můžeme ověřit, že jsou čísla již seřazena správně:
Funkcím se budeme věnovat v lekci Funkce v JavaScriptu.
Jednoduše řečeno zde metodě sort()
určíme, že má
zjistit rozdíl mezi dvěma prvky (a - b
). Protože se
tyto prvky pokoušíme odečíst, dojde k jejich přetypování
z řetězce na číslo. Pokud je a
větší než b
,
získáme kladnou hodnotu a metoda tato čísla prohodí. V opačném případě
zůstane pořadí zachováno. Porovnávání položek v poli probíhá
opakovaně až do chvíle, kdy jsou všechny prvky pole na správných pozicích
a pole je celé seřazeno.
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:
(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
Abychom vytvořili pole polí, nejprve si deklarujeme pole s názvem
kinosal
. Do toho poté pomocí cyklu vložíme nová pole
zápisem:
kinosal[i] = [];
Pomocí vnořeného cyklu pak naplníme vnořená pole daty. Definice
takového pole pro kinosál, který by na počátku obsahoval samé
0
, vypadá takto:
let kinosal = []; for (let i = 0; i < 5; i++) { kinosal[i] = []; for (let j = 0; j < 5; j++) { kinosal[i][j] = 0; // Naplnění pole nulami } }
První cyklus udává počet sloupců, druhý cyklus udává počet řádků (samozřejmě si to můžeme určit i obráceně, např. matice v matematice se zapisují opačně).
Naplnění daty
Nyní kinosál naplníme jedničkami tak, jak je vidět na obrázku:
Pro přístup k prvku 2D pole musíme samozřejmě zadat dvě souřadnice
pomocí indexů. Prostřední prvek našeho kinosálu je tedy na pozici
kinosal[2][2]
. Předešlý kód doplníme takto:
kinosal[2][2] = 1; // Ú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
Výpis pole opět provedeme pomocí cyklu, budeme potřebovat opět dva cykly (jeden nám proiteruje sloupce a druhý řádky). 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í. Abychom
získali počet řádků (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 2D využijeme HTML tabulku. Oba cykly musí mít samozřejmě jinou řídící proměnnou. Doplníme tedy tento kód:
document.write("<table border='1'>"); for (let i = 0; i < kinosal.length; i++) { document.write("<tr>"); for (let j = 0; j < kinosal[i].length; j++) { document.write("<td>"+ kinosal[i][j] + "</td>"); } document.write("</tr>"); } document.write("</table>");
Když nyní spustíme celý příklad v prohlížeči, dostaneme tento výstup:
Naplnění 2D pole ručně
Dvojrozměrné pole je možné také deklarovat a naplnit daty ručně:
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] ];
Přidáme-li k tomuto kódu cykly pro výpis všech prvků z předchozího příkladu, dostaneme v prohlížeči stejný výstup:
Výpis svátků pro daný den
Na závěr si dnes vytvoříme skript vypisující, kdo má dnes svátek.
Nejprve si vytvoříme pole, kam budeme ukládat další pole, v němž budou
uloženy svátky v daném měsíci. Pro přidání vnořených polí využijeme
metodu push()
. 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"]);
Poté zjistíme aktuální datum a pomocí metody getDate()
získáme číslo dne. Metoda vrací hodnotu 1
až
31
, pokud tedy chceme získat odpovídající index v
poli pro aktuální den, musíme odečíst 1
. Pořadové
číslo měsíce získáme 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.write("Dnes má svátek " + mesice[mesic][den]);
Výsledek:
V následujícím cvičení, Řešené úlohy k 9.-10. 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 121x (4.3 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript