IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

Doplňovanie kódu v programovacom jazyku Dart - Základné konštrukcie jazyka Dart

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

 

Predchádzajúci článok
Riešené úlohy k 9. lekcii Dart
Všetky články v sekcii
Základné konštrukcie jazyka Dart
Preskočiť článok
(neodporúčame)
Riešené úlohy k 10. lekcii Dart
Č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