9. diel - Textové reťazce v Kotlin do tretice - Split
V predchádzajúcom cvičení, Riešené úlohy k 8. lekcii Kotlin, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
Dnes si v Kotlin tutoriálu vysvetlíme ďalšie metódy na reťazci, ktoré
som vám zámerne zatajil, pretože sme nevedeli, že String
je
vlastne pole:)
Na reťazci môžeme používať mnoho metód alebo vlastností, ktoré
poznáme z poľa. Sú to napr: first()
, last()
,
indexOf()
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ť. Skúsme si to:
Tú istú ponuku možno vyvolať aj 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 sú radené abecedne a môžeme nimi listovať pomocou kurzorových šípok. IntelliJ nám zobrazuje opis metód (čo robia) a aké vyžadujú parametre.
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 počiatočnej pozície do danej koncovej pozície.
{KOTLIN_CONSOLE}
println("Wolfgang Amadeus Mozart".substring(9, 16))
{/KOTLIN_CONSOLE}
výstup:
Amadeus
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:
{KOTLIN_CONSOLE}
println("argentina".compareTo("barbados"))
{/KOTLIN_CONSOLE}
výstup:
-1
Poďme sa teraz pozrieť na ďalšiu metódu na String
, ktorá
je naozaj veľmi užitočná.
split()
a
joinToString()
Z predchádzajúceho tutoriálu vieme, že parsování reťazca znak 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 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,Dlhá 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, riadkov bodkočiarka.
Na String
môžeme volať metódu split()
, ktorá
berie ako parameter separátor (typu Char
). Následne pôvodnej
reťazec rozdelí podľa separátora 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 joinToString()
nám naopak umožňuje pole podreťazcov
spojiť oddeľovačom do jediného reťazca, parameter je oddeľovač. Výstupom
metódy je výsledný reťazec. Metódu môžeme zavolať bez parametra a tým
dôjde k spojeniu reťazcov bez oddeľovača.
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
púhe premennej typu String
, pretože majú len jeden znak. Znaky
Morseovej abecedy majú už znakov viac, tie musíme dať do poľa.
Štruktúra nášho programu by teraz mohla vyzerať nasledovne:
// reťazec, ktorý chceme dekódovať val s = ".-.. . --- -. .- .-. -.. ---" println("Pôvodná správa: $s") // reťazec s Dekódovanie správou var zprava = "" // vzorová pole val abecedniZnaky = "abcdefghijklmnopqrstuvwxyz" val morseovyZnaky = arrayOf(".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..")
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 pole podreťazcov, obsahujúcich jednotlivé
znaky morzeovky. Splitová budeme podľa znaku medzery. Pole následne
proiterujeme cyklom for
:
// rozbitie reťazca na znaky morzeovky val znaky = s.split(" ") // iterácie znakov morzeovky for (morseuvZnak in znaky) { }
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).
split()
potom vytvorí o jeden reťazec v poli viac, ktorý bude
prázdny. Ten by sme mali potom v cykle detekovať a ignorovať, my sa s tým v
Kotlin 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 reťazci
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:
val index = morseovyZnaky.indexOf(morseuvZnak) // Skontrolovanie, že sme index našli if (index != -1) { zprava += abecedniZnaky[index] }
Pokúsime sa zistiť index Morseova znaku. Ak sa to podarí, nájdeme v
abecede zodpovedajúce písmeno a to pridáme do správy. Operátor
+=
nahrádza
zprava = zprava + abecedniZnaky[index]
.
Záverom samozrejme správu vypíšeme:
{KOTLIN_CONSOLE}
// reťazec, ktorý chceme dekódovať
val s = ".-.. . --- -. .- .-. -.. ---"
println("Pôvodná správa: $s")
// reťazec s Dekódovanie správou
var zprava = ""
// vzorová pole
val abecedniZnaky = "abcdefghijklmnopqrstuvwxyz"
val morseovyZnaky = arrayOf(".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..")
// rozbitie reťazca na znaky morzeovky
val znaky = s.split(" ")
// iterácie znaky morzeovky
for (morseuvZnak in znaky) {
val index = morseovyZnaky.indexOf(morseuvZnak)
// Skontrolovanie, že sme index našli
if (index != -1) {
zprava += abecedniZnaky[index]
}
}
println("Dekódovaná správa: $zprava")
{/KOTLIN_CONSOLE}
výstup:
Pôvodná správa: .-.. . --- -. .- .-. -.. --- Dekódovaná správa: leonardo
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 joinToString()
sa stretneme počas Kotlin
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ť:
{KOTLIN_CONSOLE}
println("Prvý riadok\nDruhý riadok")
{/KOTLIN_CONSOLE}
Znak \
označuje nejakú špeciálnu sekvenciu znakov v reťazci
a je ďalej využívaný napr. K písanie unicode znaku ako
\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:
{KOTLIN_CONSOLE}
println("Toto je spätné lomítko: \\")
{/KOTLIN_CONSOLE}
Rovnakým spôsobom môžeme odescapovat napr. Úvodzovky tak, aby ju Kotlin nechápal ako koniec reťazca:
{KOTLIN_CONSOLE}
println("Toto je úvodzovky: \"")
{/KOTLIN_CONSOLE}
Vstupy z konzoly a polí v okenných aplikáciách sa samozrejme escapují
samy, aby užívateľ nemohol zadať \n
a podobne. V kóde to má
programátor povolené a musia na to myslieť.
Raw string
Občas potrebujeme zapísať viac spätných lomítok v jednom textovom
reťazci. Keby sme ich všetky escapovali, mohlo by to znepřehlednit náš
kód. Kvôli tomuto problému možno v Kotlin deklarovať tzv. Raw string.
Stačí obaliť text do """
a všetka spätné lomítka sa
správajú ako obyčajné znaky.
{KOTLIN_CONSOLE}
println("""V tomto stringu nemusím nič escapovat \""")
{/KOTLIN_CONSOLE}
V nasledujúcom cvičení, Riešené úlohy k 9. lekcii Kotlin, 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é 43x (7.71 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Kotlin