10. diel - Textové reťazce v Dart do tretice - split a join
V predchádzajúcom cvičení, Riešené úlohy k 9. lekcii Dart, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V on-line Dart kurzu sme si v minulej lekcii, Riešené úlohy k 9. lekcii Dart , ukázali, že
String
je vlastne zoznam znakov. Dnes si vysvetlíme ďalšie
metódy na reťazci, ktoré som vám zámerne zatajil, pretože sme nevedeli,
že String
je vlastne niečo ako zoznam:)
Na reťazci môžeme používať mnoho metód a vlastností, ktoré poznáme
zo zoznamov. Sú to napr: contains()
, indexOf()
,
substring()
namiesto sublist()
, length
a
ďalšie.
Keď si vytvoríme ľubovoľnú premennú a napíšeme za ňu bodku, IntelliJ IDEA nám zobrazí ponuku všetkých metód a vlastností (a tiež premenných, ale k tomu sa dostaneme až pri objektoch), ktoré na ňu môžeme volať. Napovedanie nám spríjemní prácu s kódom, ktorý za nás dopĺňa. Skúsme si to:
Tú istú ponuku možno vyvolať tiež stlačením CTRL + Medzerník v prípade, že textový kurzor umiestnime na bodku. Samozrejme to platí pre všetky premenné aj triedy a budeme toho využívať čoraz častejšie. Metódy a vlastnosti sú zoradené podľa dôležitosti a môžeme nimi listovať pomocou kurzorových šípok. IDEA nám zobrazuje aké vyžadujú parametre, čo vracajú a môžeme si nechať zobraziť aj popis (čo robia) pomocou CTRL + Q.
Povedzme si o nasledujúcich metódach a ukážme si ich na jednoduchých príkladoch:
Ďalšie metódy na reťazci
Substring ()
Vráti podreťazec od danej pozície do konca reťazca. Môžeme zadať druhý parameter, ktorým je dĺžka podreťazca.
print('Kdo se směje naposled, ten je admin.'.substring(13, 13 + 8));
Výstup programu:
Konzolová aplikácia
naposled
CompareTo ()
Umožňuje porovnať dva reťazce podľa abecedy. Vracia -1
ak
je prvý reťazec pred reťazcom v parametri, 0
ak sú rovnaké a
1
ak je za ním:
print('akát'.compareTo('blýskavice'));
Výstup programu:
Konzolová aplikácia
-1
StartsWith ()
Vráti logickú hodnotu podľa toho, či reťazec začína podľa vzoru v parametri.
print('Hajej, hajej, pacholátko, houpe tě tvá maminka.'.startsWith('Hajný')); print('Hajej, hajej, pacholátko, houpe tě tvá maminka.'.startsWith('Hajej')); print('Hajej, hajej, pacholátko, houpe tě tvá maminka.'.startsWith('HAJEJ'));
Výstup programu:
Konzolová aplikácia
false
true
false
EndsWith ()
print('Paci, paci, pacičky, máma koupí botičky.'.endsWith('botasky.')); print('Paci, paci, pacičky, máma koupí botičky.'.endsWith('botičky.')); print('Paci, paci, pacičky, máma koupí botičky.'.endsWith('BOTIČKY.'));
Výstup programu:
Konzolová aplikácia
false
true
false
Vráti logickú hodnotu podľa toho, či reťazec končí podľa vzoru v parametri.
Poďme sa teraz pozrieť na 2 ďalšie metódy na String, ktoré sú naozaj veľmi užitočné.
Split () a join ()
Z predchádzajúcej lekcie Dart vieme, že parsování reťazca po znaku
môže byť niekedy celkom zložité a to sme robili pomerne jednoduchý
príklad. S reťazci sa samozrejme budeme stretávať stále, a to ako na vstupe
od užívateľa (napr. Z konzoly alebo z polí v okenných aplikáciách), tak
napr. V súboroch TXT a XML. Veľmi často máme zadaný jeden dlhší
String
(riadok súboru alebo riadok konzoly), v ktorom je viac
hodnôt, oddelených tzv. Separátory, napr. Čiarkou. V tomto prípade
hovoríme o formáte CSV (Comma-Separated Values, teda hodnoty oddelené
čiarkou). Aby sme si boli istí, že vieme, o čom hovoríme, ukážme si
nejaké ukážkové reťazca:
Jan,Novák,Dlouhá 10,Praha 3,130 00 .. ... .-.. .- -. -.. ... --- ..-. - (1,2,3;4,5,6;7,8,9)
- Prvý reťazec je očividne nejaký užívateľ, takto by sme mohli napr. Realizovať uloženie užívateľov do CSV súboru, každý na jeden riadok.
- Druhý reťazec sú znaky Morseovej abecedy, separátor (oddeľovač) je tu medzera.
- Tretí reťazec je matica o 3 stĺpcoch a 3 riadkoch. Oddeľovač stĺpcov je čiarka, riadok bodkočiarka.
Na STRING môžeme volať metódu split()
, ktorá berie ako
parameter separátor (oddeľovač). Následne pôvodnej reťazec rozdelí podľa
separátorov na pole podreťazcov, ktoré vráti. To nám veľmi uľahčí
prácu pri rozdeľovaní hodnôt v reťazci.
Metóda join()
sa nevolá priamo na type String
,
ale na zozname (akéhokoľvek typu), a umožňuje nám naopak zoznam spojiť
oddeľovačom do jediného reťazca, parametrom je oddeľovač. Výstupom
metódy je výsledný reťazec. Ak je prvkom zoznamu iný dátový typ ako
String
, vykoná sa jeho konverzia na reťazec.
Keďže nevieme tvoriť objekty (používateľa) a ani pracovať s viacrozmernými poliami (matice), skúsime si naprogramovať dekodér správ z Morseovej abecedy.
Dekodér Morseovej abecedy
Poďme si opäť pripraviť štruktúru programu. Budeme potrebovať 2 reťazca so správou, jeden so správou v Morseovej abecede, druhý zatiaľ prázdny, do ktorého budeme ukladať výsledok nášho snaženia. Ďalej budeme ako v prípade samohlások potrebovať nejaký vzor písmen. K písmenám samozrejme vzor ich znaku v morzeovce. Písmená môžeme opäť uložiť do jednoduchého STRING, pretože majú len jeden znak. Znaky Morseovej abecedy majú už znakov viac, tie musíme dať do zoznamu.
Štruktúra nášho programu by teraz mohla vyzerať nasledovne:
// řetězec, který chceme dekódovat String s = '.. - -. . - .-- --- .-. -.-'; print('Původní zpráva: $s'); // řetězec s dekódovanou zprávou String zprava = ''; // vzorové abecedy String abecedniZnaky = 'abcdefghijklmnopqrstuvwxyz'; List<String> morseovyZnaky = ['.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '....', '..', '.---', '-.-', '.-..', '--', '-.', '---', '.--.', '--.-', '.-.', '...', '-', '..-', '...-', '.--', '-..-', '-.--', '--..'];
Môžete si potom pridať ďalšie znaky ako čísla a interpunkčné
znamienka, my ich tu vynecháme. Teraz si reťazec s rozbijeme metódou
split()
na zoznam podreťazcov, obsahujúcich jednotlivé znaky
morzeovky. Splitová budeme podľa znaku medzery. Pole následne proiterujeme
metódou forEach()
:
// rozbití řetězce na znaky morzeovky List<String> znaky = s.split(' '); // iterace znaků morzeovky znaky.forEach((String morseuvZnak) { });
Ideálne by sme sa mali nejako vysporiadať s prípadmi, kde užívateľ
zadá napr. Viac medzier medzi znakmi (to užívatelia radi robia). Metóda
split()
potom vytvorí o jeden reťazec v zozname viac, ktorý bude
prázdny. Ten by sme mali potom v cykle detekovať a ignorovať, my sa s tým v
tutoriálu nebudeme zaoberať.
V cykle sa pokúsime nájsť aktuálne čítaný znak morzeovky v poli
morseovyZnaky
. Bude nás zaujímať jeho index, pretože keď sa
pozrieme na ten istý index v poli abecedniZnaky
, bude tam
zodpovedajúce písmeno. To je samozrejme z toho dôvodu, že ako pole tak
reťazec obsahujú rovnaké znaky, zoradené podľa abecedy. Umiestni do tela
cyklu nasledujúci kód:
String abecedniZnak = '?'; int index = morseovyZnaky.indexOf(morseuvZnak); if (index >= 0) // znak nalezen abecedniZnak = abecedniZnaky[index]; zprava += abecedniZnak;
Kód najprv do abecedného znaku uloží '?'
, Pretože sa môže
stať, že znak v našej sade nemáme. Následne sa pokúsime zistiť jeho
index. Ak sa to podarí, dosadíme do abecedniZnak
znak z
abecedných znakov pod týmto indexom. Nakoniec znak pripojíme k správe.
Operátor +=
nahrádza
zprava = zprava + abecedniZnak
.
Záverom samozrejme správu vypíšeme:
print('Dekódovaná zpráva: $zprava');
Výstup programu:
Konzolová aplikácia
Původní zpráva: .. - -. . - .-- --- .-. -.-
Dekódovaná zpráva: itnetwork
Hotovo! Za úlohu máte si naprogramovať program opačný, ktorý naopak
zakóduje reťazec do morzeovky; kód bude veľmi podobný. Sa
split()
a join()
sa stretneme počas kurzu ešte
niekoľkokrát.
Špeciálne znaky alebo uvádzacích
Textový reťazec môže obsahovať špeciálne znaky, ktoré sú predsadené
spätným lomítkom \
. Je to najmä znak \n
, ktorý
kdekoľvek v texte spôsobí odriadkovanie a potom \t
, kde sa
jedná o tabulátor.
Poďme si to vyskúšať:
print('První řádka\nDruhá řádka');
Znak \
označuje nejakú špeciálnu sekvenciu znakov v reťazci
a je ďalej využívaný napr. K písanie Unicode znaku ako \uxxxx
,
čo je ekvivalentné \u{xxxx}
, kde xxxx
je kód
znaku.
Problém môže nastať vo chvíli, keď chceme napísať samotné
\
, musíme ho tzv. Odescapovat:
print('Toto je zpětné lomítko: \\');
Rovnakým spôsobom môžeme odescapovat napr. Úvodzovky tak, aby ju Dart nechápal ako koniec reťazca:
print("Toto je uvozovka: \"");
Problém môže byť, keď chceme zapísať nejakú dlhšiu cestu k súboru,
kde máme veľké množstvo spätných lomítok. Aj na to Dart myslí a zaviedli
modifikátor r
( "raw" string), vďaka ktorému Dart automaticky
escapuje celý nami napísaný reťazec v kóde (teda každý znak stratí svoj
špeciálny význam):
print(r'D:\git\itnetwork'); print(r'V proměnné a je obsah $a.');
Vstupy z premenných a polí sa samozrejme escapují samy, aby užívateľ
nemohol zadať $a
a podobne. V kóde to má programátor povolené
a musia na to myslieť.
V budúcej lekcii, Riešené úlohy k 10. lekcii Dart , sa pozrieme na vnorené zoznamy a ako s nimi pracovať.
V nasledujúcom cvičení, Riešené úlohy k 10. lekcii Dart, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
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é 5x (2.41 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Dart