IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

11. diel - Vnorené zoznamy v Dart

V predchádzajúcom cvičení, Riešené úlohy k 10. lekcii Dart, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

V minulej lekcii, Riešené úlohy k 10. lekcii Dart , sme si uviedli metódy split() a join() na textových reťazcoch. Dnešné Dart tutoriál pojednáva o tzv. Viacrozmerných poliach, pre nás konkrétne o vnorených zoznamoch.

Už vieme pracovať s jednorozmernými poľom (zoznamom), ktoré si môžeme predstaviť ako riadku priehradok v pamäti počítača.

Zoznam v jazyku Dart - Základné konštrukcie jazyka Dart

(Na obrázku je vidieť pole ôsmich čísiel)

Hoci to nie je tak časté, v programovaní sa občas stretávame aj s viacrozmernými poliami a to najmä ak programujeme nejakú simuláciu (napr. Hru).

Dvojrozmerné pole

Dvojrozmerné pole si môžeme v pamäti predstaviť ako tabuľku a mohli by sme takto reprezentovať napr. Rozohranú partiu piškvoriek. Ak by sme sa chceli držať reálnych aplikácií, ktoré budete neskôr v zamestnaní tvoriť, môžeme si predstaviť, že do 2D poľa budeme ukladať informácie o obsadenosť sedadiel v kinosály. Situáciu by sme si mohli graficky znázorniť napr. Nasledovne:

2D polia v Dart - Základné konštrukcie jazyka Dart

(Na obrázku je vidieť 2d pole reprezentujúci obsadenosť kinosály)

Kinosála by bol v praxi samozrejme väčší, ale ako ukážka nám toto pole postačí. Hodnota 0 označuje voľno, 1 obsadené. Neskôr by sme mohli doplniť aj 2 - Rezervované a podobne. Pre tieto stavy by bolo správnejšie vytvoriť si vlastný dátový typ, tzv. Výpočet, ale s ním sa stretneme až neskôr, takže si teraz musíme vystačiť iba s číslami.

Pripomeniem, že pole je pre nás v Dart zoznam. Vnorený zoznam v Dart deklarujeme nasledujúcim spôsobom:

List<List<int>> kinosal = [];

V tomto prípade chceme kinosála na začiatku definovať do určitého tvaru. To docielime tak, že by sme vo for cykle pridali do zoznamu zoznamy, do ktorých by sme pridali danej hodnoty. Alebo použijeme sofistikovanejšie zápis, ktorý sa pre jeho momentálnej náročnosť v rámci tohto tutoriálu nebudeme snažiť vysvetliť.

List<List<int>> kinosal = new List.generate(5, (_) => new List.filled(5, 0));

Popíšem kód aspoň jednoducho, aj keď zatiaľ nevieme, prečo to takto funguje: vytvoríme si zoznam, ktorý v sebe vygeneruje 5x zoznam, ktorý v sebe má 5x číslo 0.

Prvá číslica udáva počet stĺpcov, druhá počet riadkov (samozrejme si to môžeme určiť aj obrátene, napr. Matice v matematike sa zapisujú opačne).

Naplnenie dátami

Teraz kinosála naplníme jednotkami tak, ako je vidieť na obrázku vyššie. Pretože budeme ako správni programátori leniví, využijeme na vytvorenie riadku jedničiek for cykly.:) Pre prístup k prvku zoznamu musíme samozrejme zadať 2 súradnice. Vypíšeme si tiež obsah kinosály pred a po:

print(kinosal);
kinosal[2][2] = 1; // Prostředek
for (int i = 1; i < 4; i++) // 4. řádek
{
    kinosal[i][3] = 1;
}
for (int i = 0; i < 5; i++) // Poslední řádek
{
    kinosal[i][4] = 1;
}
print(kinosal);

Výstup programu:

Konzolová aplikácia
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
[[0, 0, 0, 0, 1], [0, 0, 0, 1, 1], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1]]

Ako ide vidieť, jedničky sa nám niekde zapísali a ak porovnáme výstup s obrázkom vyššie, naozaj sa všetko i zhoduje.

Výpis

Výpis pole opäť vykonáme pomocou cyklu, na vnorený budeme potrebovať cykly 2 (jeden nám proiteruje stĺpce a druhý riadky). Ako správni programátori nevložíte počet riadkov a stĺpcov do cyklov napevno, pretože sa môže zmeniť. Využijeme vlastnosti length na zozname. Pozor ale, že vráti počet prvkov v konkrétnom zozname, nie celkový počet. Výraz kinosal.length nám vráti počet stĺpcov, kinosal.first.length vráti počet sedadiel v prvom stĺpci. Keďže v našom kine majú všetky stĺpce rovnaký počet sedadiel, môžeme druhú hodnotu brať ako počet radov sály.

for (int j = 0; j < kinosal.length; j++)
{
    for (int i = 0; i < kinosal.first.length; i++)
    {
        stdout.write(kinosal[i][j]);
    }
    stdout.writeln();
}

Výstup programu:

Konzolová aplikácia
00000
00000
00100
01110
11111

Aj náš výpis vnoreného zoznamu dopadol dobre. Podobne by sme takto mohli tvoriť aj viac zanorené zoznamy, stačilo by do položiek vnoreného zoznamu vygenerovať ďalšie zoznamy. Celok si potom môžeme predstaviť ako by kinosála mal ešte ďalšie poschodia.

3D poľa v programovacom jazyku Dart - Základné konštrukcie jazyka Dart

Zoznam zoznamov

Niekedy nepožadujeme všetky zoznamy v zozname rovnako veľké, výsledkom bude "zubatý" zoznam zoznamov ako na obrázku nižšie.

Zubatá polia v programovacom jazyku Dart - Základné konštrukcie jazyka Dart

Výhodou je, že do každého riadku / stĺpca môžeme uložiť ako veľký zoznam chceme. V niektorých prípadoch teda nemusíme "plytvať" pamäťou na celú tabuľku a môžeme zoznam vytvoriť takto "zubato" (anglicky Jagged).

Takýto zoznam vytvoríme jednoducho pomocou deklarácie, ktorú sme už raz skúšali:

List<List<int>> kinosal = [];

Nevýhodou tohto prístupu je, že si všetky hodnoty musíme vložiť sami a musíme tiež kontrolovať, že prvok, ktorý chceme získať, naozaj existuje.

Ručné inicializácia vnorených zoznamov

Ešte si ukážeme, že aj pre vnorené zoznamy je možné použiť definíciu formou doslovný:

List<List<int>> kinosal = [
    [0, 0, 0, 0, 1],
    [0, 0, 0, 1, 1],
    [0, 0, 1, 1, 1],
    [0, 0, 0, 1, 1],
    [0, 0, 0, 0, 1],
];

(Pole je v tejto zápisnici otočené, keďže definujeme stĺpce, ktoré tu zapisujeme ako riadky).

Na záver by som rád dodal, že niektorí ľudia, ktorí nevie správne používať objekty, využívajú vnorené zoznamy na ukladanie viac údajov o jedinej entite. Napr. budeme chcieť uložiť výšku, šírku a dĺžku piatich mobilných telefónov. Hoci sa vám teraz môže zdať, že sa jedná o úlohu na 3D pole, v skutočnosti sa jedná o úlohu na obyčajné 1D pole (presnejšie zoznam) objektov typu Telefon. Ale o tom až u objektovo orientovaného programovania.

V budúcej lekcii, Matematické funkcie v Dart a knižnica dart: math , sa pozrieme na matematické funkcie.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 10x (1.78 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Dart

 

Predchádzajúci článok
Riešené úlohy k 10. lekcii Dart
Všetky články v sekcii
Základné konštrukcie jazyka Dart
Preskočiť článok
(neodporúčame)
Matematické funkcie v Dart a knižnica dart: math
Článok pre vás napísal Honza Bittner
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity