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í.

Lekce 8 - Seznamy v Dartu

V minulé lekci kurzu, Ošetření uživatelských vstupů v Dartu, jsme si ukázali ošetření uživatelských vstupů. Dnes si v tutoriálu programovacího jazyka Dart představíme datovou strukturu seznam a vyzkoušíme si, co všechno umí.

Seznam

Představte si, že si chcete uložit nějaké údaje o více prvcích. Např. chcete v paměti uchovávat 10 čísel, políčka šachovnice nebo jména 50ti uživatelů. Asi vám dojde, že v programování bude nějaká lepší cesta, než začít bušit proměnné uzivatel1, uzivatel2... až uzivatel50. Nehledě na to, že jich může být třeba 1000. A jak by se v tom potom hledalo? Brrr, takhle ne. :)

Pokud potřebujeme uchovávat větší množství proměnných stejného typu, tento problém nám řeší seznam. Můžeme si ho představit jako řadu přihrádek, kde v každé máme uložený jeden prvek. Přihrádky jsou očíslované tzv. indexy, první má index 0.

Pole v programovacím jazyce Dart - Základní konstrukce jazyka Dart

Programovací jazyky se velmi liší v tom, jak s podobnými datovými strukturami pracují. V některých jazycích (zejména starších, kompilovaných) nebylo možné za běhu programu vytvořit seznam s dynamickou velikostí (např. mu dát velikost dle nějaké proměnné). Takovým seznamům se říká pole. Pole se muselo deklarovat s konstantní velikostí přímo ve zdrojovém kódu. Toto se obcházelo tzv. pointery a vlastními datovými strukturami, což často vedlo k chybám při manuální správě paměti a nestabilitě programu (např. v C++). Naopak některé interpretované jazyky umožňují nejen deklarovat seznam s libovolnou velikostí, ale dokonce tuto velikost na již existujícím seznamu měnit (např. PHP). Jak jsem již říkal, v Dartu je vše objekt. V rámci tohoto kurzu nám bude stačit vědět, co to seznam obecně je a že kolekce jsou chytré datové struktury, které nám usnadňují práci. O kolekcích jako takových si něco povíme až v kurzu o Objektovém programování v Dart.

Seznam je jednoduchý, prvky jsou za sebou a můžeme je snadno procházet. Pro hromadnou manipulaci s prvky seznamu se používají cykly. To samé platí i pro seznamy v Dartu, proto jsou ideálním kandidátem, kterého budeme používat.

Seznam deklarujeme jako List (což je seznam anglicky) a do špičatých závorek přidáme typ položek seznamu.

List<int> seznam;

Seznam je samozřejmě název naší proměnné. Nyní jsme však pouze deklarovali, že v proměnné bude seznam intů. Nyní ho musíme založit, abychom ho mohli používat. K tomu buď využijeme literál (možnost, jak explicitně něco zapsat, např. 3 pro celočíselný literál). Literál pro seznam je [ ], nebo použijeme klíčové slovo new, které se využívá u složitějších objektů, což si vysvětlíme podrobněji v již zmíněném navazujícím kurzu.

List<int> seznam = [];
List<int> seznam2 = new List();

Nyní máme v proměnné seznam a seznam2 seznamy, které se samy zvětšují či zmenšují podle potřeb.

Do seznamu přidáváme prvky metodou add(), která jako parametr bere daný prvek. K prvkům seznamů přistupujeme přes hranatou závorku, do které píšeme index daného prvku (ten musí existovat).

seznam.add(1);
print(seznam[0]);

Plnit seznam takhle ručně by bylo příliš pracné, použijeme cyklus a naplníme si seznam čísly od 1 do 10. K naplnění použijeme for cyklus:

for (int i = 0; i < 10; i++)
    seznam.add(i + 1);

Abychom seznam vypsali, můžeme za předchozí kód připsat:

for (int i = 0; i < seznam.length; i++)
    print(seznam[i]);

Výstup programu:

Konzolová aplikace
1
2
3
4
5
6
7
8
9
10

Všimněte si, že seznam má vlastnost length, kde je uložena jeho délka, tedy počet prvků.

A nebo, protože jak jsem zmiňoval, seznam v Dartu je kolekce a ta se umí sama vypsat, můžeme vypsat celý seznam najednou pomocí metody print():

print(seznam);

Výstup programu:

Konzolová aplikace
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Můžeme použít zjednodušenou verzi cyklu pro práci s kolekcemi, známou jako foreach. Ten projede všechny prvky v seznamu a jeho délku si zjistí sám. Jeho syntaxe pro náš seznam je následující:

for (datovytyp promenna in kolekce) {
    // příkazy
}

Kolekce v Dartu mají navíc metody na zjednodušený zápis foreach cyklu a dalších speciálních cyklů.

kolekce.forEach((datovytyp promenna) {
    // příkazy
});

Cyklus projede prvky v kolekci (to je obecný název pro struktury, které obsahují více prvků, u nás to bude seznam) postupně od prvního do posledního. Prvek máme v každé iteraci cyklu uložený v dané proměnné.

Přepišme tedy náš dosavadní program na metodu forEach(). Foreach nemá řídící proměnnou, není tedy vhodný pro vytvoření našeho seznamu a použijeme ho jen pro výpis.

seznam.forEach((int promenna) {
    stdout.write('$promenna ');
});

Výstup programu:

Konzolová aplikace
1 2 3 4 5 6 7 8 9 10

Seznam samozřejmě můžeme naplnit ručně a to i bez toho, abychom prvky postupně dosazovali. Použijeme k tomu literál seznamu, který jsem zmiňoval již dříve, a prvky v něm oddělíme čárkou:

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];

Seznam často slouží k ukládání mezivýsledků, které se potom dále v programu používají. Když potřebujeme nějaký výsledek 10x, tak to nebudeme 10x počítat, ale spočítáme to jednou a uložíme do seznamu, odtud poté výsledek jen načteme.

Metody a vlastnosti na třídě List

Samotný List obsahuje řadu užitečných metod a vlastností pro práci se seznamy. Pojďme se na ně podívat:

sort()

Jak již název napovídá, metoda nám seznam seřadí. Její jediný parametr je komparátor, speciální metoda, která určí, jak položky v seznamu setřídit. String má v Dartu metodu, která porovná sebe vůči jinému Stringu. Tuto metodu využijeme. Zkusme si setřídit a vypsat naši rodinku Simpsnů:

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];
print(simpsonovi);
simpsonovi.sort((String a, String b) => a.compareTo(b));
print(simpsonovi);

Výstup programu:

Konzolová aplikace
[Homer, Marge, Bart, Lisa, Meggie]
[Bart, Homer, Lisa, Marge, Meggie]

Zkuste si vytvořit seznam čísel a vyzkoušejte si, že to opravdu funguje i pro ně. Stejně tak i int má metodu compareTo().

reversed

Vlastnost reversed nám vrátí otočený seznam (první prvek bude jako poslední atd.), toho můžeme využít např. pro třídění pozpátku. Tato vlastnost nevrací seznam, ale obecnou kolekci, kterou lze procházet. Pokud bychom chtěli vrátit seznam, na vlastnost reversed zavoláme ještě metodu toList().

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];
simpsonovi.sort((String a, String b) => a.compareTo(b));
print(simpsonovi.reversed);
print(simpsonovi.reversed.toList());

Výstup programu:

Konzolová aplikace
(Meggie, Marge, Lisa, Homer, Bart)
[Meggie, Marge, Lisa, Homer, Bart]

indexOf() a lastIndexOf()

Tyto metody vrátí index prvního nebo posledního nalezeného prvku. V případě nenalezení prvku vrátí -1. Každá z metod bere dva parametry, prvním je hledaný prvek, druhý nepovinný parametr je index, od kterého začít. Umožníme uživateli zadat jméno Simpsna a řekneme mu, na jaké pozici je uložený. Teď to pro nás nemá hlubší význam, protože prvek seznamu je jen String. Bude se nám to však velmi hodit ve chvíli, kdy v poli budeme mít uloženy plnohodnotné objekty. Berme to tedy jako takovou přípravu.

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];
print('Ahoj, zadej svého oblíbeného Simpsna (z rodiny Simpsnů): ');
String simpson = stdin.readLineSync(encoding: UTF8);
int pozice = simpsonovi.indexOf(simpson);
if (pozice >= 0)
    print('Jo, to je můj ${pozice + 1}. nejoblíbenější Simpson!');
else
    print('Hele, tohle není Simpson!');

Výstup programu:

Konzolová aplikace
Ahoj, zadej svého oblíbeného Simpsna (z rodiny Simpsnů):
Homer
Jo, to je můj 1. nejoblíbenější Simpson!

sublist()

Sublist vrací výřez seznamu od startovního indexu do konce nebo do koncového indexu, přičemž tento index se ve výřezu již neobjeví.

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];
print(simpsonovi.sublist(2, 4));

Výstup programu:

Konzolová aplikace
[Bart, Lisa]

length

Vlastnost length jsme si již zmínili, vrátí délku seznamu. Není metodou, ale vlastností, nepíší se za ni tedy závorky ().

first a last

Vlastnosti vracející první a poslední prvek seznamu.

take() a skip()

Obě tyto metody berou jako parametr počet prvků. Take vrátí seznam s daným počtem prvků zkopírovaných od začátku původního seznamu. Skip() naopak vrátí seznam bez těchto prvních prvků.

contains()

Metoda vrací true/false podle toho, zda se prvek, uvedený v parametru metody, v daném poli nachází.

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];
print(simpsonovi.contains('Bart'));
print(simpsonovi.contains('Superman'));

Výstup programu:

Konzolová aplikace
true
false

shuffle()

Shuffle() je metoda, která náhodně prohází prvky seznamu. Nic nevrací, operuje nad konkrétním seznamem, kterému v zásadě jen prohází indexy.

List<String> simpsonovi = ['Homer', 'Marge', 'Bart', 'Lisa', 'Meggie'];
print(simpsonovi);
simpsonovi.shuffle();
print(simpsonovi);
simpsonovi.shuffle();
print(simpsonovi);

Výstup programu:

Konzolová aplikace
[Homer, Marge, Bart, Lisa, Meggie]
[Bart, Marge, Lisa, Homer, Meggie]
[Homer, Bart, Marge, Meggie, Lisa]

To by pro dnešek stačilo, můžete si se seznamem hrát. V příští lekci, Řešené úlohy k 7.-8. lekci Dartu, na vás čeká překvapení. ;-)

V následujícím cvičení, Řešené úlohy k 7.-8. lekci Dartu, 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 6x (2.15 kB)
Aplikace je včetně zdrojových kódů v jazyce Dart

 

Předchozí článek
Ošetření uživatelských vstupů v Dartu
Všechny články v sekci
Základní konstrukce jazyka Dart
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 7.-8. lekci Dartu
Článek pro vás napsal Honza Bittner
Avatar
Uživatelské hodnocení:
4 hlasů
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity