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

12. diel - Textové reťazce v JavaScripte druhýkrát - Práca so znakmi

V minulej lekcii, Najčastejšie chyby JS nováčikov - Vieš pomenovať premenné?, sme si ukázali najčastejšie chyby začiatočníkov v JavaScripte ohľadom pomenovania premenných.

V dnešnom JavaScript tutoriále sa budeme zaoberať prístupom k jednotlivým znakom textového reťazca a predstavíme si ďalšie metódy pre prácu s reťazcami.

Textový reťazec

Pokiaľ ste vycítili nejakú podobnosť medzi poľom a textovým reťazcom, tak ste vycítili správne. Pre ostatných môže byť prekvapením, že je dátový typ string v podstate poľa jednotlivých znakov a môžeme s ním aj takto pracovať.

Práca so znakmi reťazca

Najprv si vyskúšajme, že to všetko funguje. Rozcvičíme sa na jednoduchom vypísaní znaku na danej pozícii. Jednotlivé znaky v reťazci môžeme vybrať pomocou indexu. Index sa zapisuje do hranatých zátvoriek za názvom premennej. Čísluje sa od nuly, prvému znaku teda zodpovedá index [0]:

let language = "JavaScript";
document.write(language[0]); // prints the first character of the string
document.write(language[4]); // prints the fifth character of the string

Výstup:

Your page
localhost

Znaky na danej pozícii sú v JavaScripte read-only, nemôžeme ich teda jednoducho zmeniť. Samozrejme to ide urobiť inak, neskôr si to ukážeme, zatiaľ sa budeme venovať iba čítaniu jednotlivých znakov.

Metóda charAt()

Znak na danom indexe môžeme nájsť aj pomocou metódy charAt(). V jej parametri zadáme index znaku v reťazci (opäť počnúc 0). Predchádzajúci kód by sme zapísali takto:

let language = "JavaScript";
document.write(language.charAt(0));
document.write(language.charAt(4));

Výstup:

Your page
localhost

V praxi použijeme skôr prvý zápis. Ak v ňom zadáme neplatný index (v našom prípade napríklad číslo 15), získame hodnotu undefined. Oproti tomu metóda charAt() v takom prípade vráti prázdny reťazec.

Metóda indexOf()

A teraz sa pozrieme na zistenie pozície daného znaku v texte. Číselný index tejto pozície získame pomocou metódy indexOf(). Ako parameter jej teda odovzdáme hľadaný znak. Metóda vracia index prvého výskytu daného znaku a pokiaľ ho v reťazci nenájde vráti hodnotu -1.

Skúsme si vypísať index znaku a, s a nejaký znak, ktorý v texte nie je, napríklad x:

let language = "JavaScript";
document.write(language.indexOf("a"));
document.write("<br />");
document.write(language.indexOf("s"));
document.write("<br />");
document.write(language.indexOf("x"));

Výstup:

Your page
localhost

Vidíme, že znak s v texte JavaScript nebol nájdený. Metóda indexOf() totiž rozlišuje medzi veľkými a malými písmenami. Pokiaľ by sme jej v parametri zadali veľké S, získali by sme index 4.

Metóda lastIndexOf()

Ak chceme zistiť pozíciu posledného výskytu daného znaku alebo podreťazca v texte, použijeme metódu lastIndexOf():

let language = "JavaScript";
document.write(language.lastIndexOf("a"));

Výstup:

Your page
localhost

Metóda substring()

Teraz si ešte ukážeme, ako získať vybranú časť reťazca, ktoré sa hovorí podreťazec:

let composer = "Wolfgang Amadeus Mozart";
document.write(composer.substring(9, 16));

Výstup:

Your page
localhost

V JS existovala aj metóda substr(), ktorá je teraz označená ako zastaraná.

ASCII hodnota

Možno ste už niekedy počuli o tabuľke ASCII. Najmä v ére operačného systému MS-DOS prakticky nebola iná možnosť, ako zaznamenávať text. Jednotlivé znaky boli uložené ako čísla typu byte, teda s rozsahom hodnôt od 0 do 255. V systéme bola uložená tzv. ASCII tabuľka, ktorá mala tiež 256 znakov a každému ASCII kódu (číselnému kódu) priraďovala jeden znak.

Asi je vám jasné, prečo tento spôsob nepretrval dodnes. Do tabuľky sa jednoducho nezmestili všetky znaky všetkých národných abecied, teraz sa používa Unicode (UTF-8) kódovanie, kde sú znaky reprezentované trochu iným spôsobom. Napriek tomu máme stále možnosť pracovať s ASCII hodnotami jednotlivých znakov. Hlavná výhoda je v tom, že znaky sú uložené v tabuľke za sebou, podľa abecedy. Napr. na pozícii 97 nájdeme znak a, na pozícii 98 znak b a podobne. Podobne je to s číslami, diakritické znaky tam budú bohužiaľ len nejako rozhádzané.

Skúsme si teraz previesť znak do jeho ASCII hodnoty. Využijeme na to metódu charCodeAt() a ako parameter jej zadáme index 0:

let character = "a";
let asciiValue = character.charCodeAt(0); // Converts a character to its ASCII value
document.write(`Character '${character}' has been converted to ASCII value ${asciiValue}`);

Výstup:

Your page
localhost

Pomocou metódy String.fromCharCode() naopak vytvoríme určitý znak, keď jej v parametri zadáme číselnú ASCII hodnotu:

let asciiValue = 98;
let character = String.fromCharCode(asciiValue); // Converts an ASCII value to a character
document.write(`ASCII value ${asciiValue} has been converted to character '${character}'`);

Výstup:

Your page
localhost

Caesarova šifra

Nakoniec si vytvoríme jednoduchý program na šifrovanie textu. Ak ste niekedy počuli o Caesarovej šifre, bude to presne to, čo si tu naprogramujeme. Šifrovanie textu spočíva v posúvaní znaku v abecede o určitý, pevne stanovený počet znakov. Napríklad slovo hello sa s posunom textu o 1 preloží ako "ifmmp". Posun umožníme užívateľovi vybrať. Algoritmus tu máme samozrejme opäť vysvetlený a to v článku Caesarova šifra. Program si dokonca môžete vyskúšať v praxi - Online caesarova šifra.

Vráťme sa k programovaniu a pripravme si kód. Budeme potrebovať premenné pre:

  • pôvodný text,
  • zašifrovanú správu
  • a pre posun.

Ďalej si pripravíme cyklus prechádzajúci jednotlivými znakmi a výpis zašifrovanej správy. Správu si necháme zapísanú napevno v kóde, aby sme ju nemuseli pri každom spustení programu písať. Šifra nepočíta s diakritikou, medzerami a interpunkčnými znamienkami:

// initialization of variables
let originalMessage = "gaiusjuliuscaesar";
document.write("Original message: " + originalMessage);
document.write("<br />");

let encryptedMessage = "";
let shift = 1;

// loop through individual characters
for (let i = 0; i < originalMessage.length; i++) {
    // ...
}

// message print
document.write("Encrypted message: " + encryptedMessage);

Teraz sa presunieme dovnútra cyklu, v ňom postupne získame ASCII hodnotu (čiže ordinálnu hodnotu) jednotlivých znakov, túto hodnotu zakaždým zvýšime o shift a prevedieme na znak. Tento znak nakoniec pripojíme k výslednej správe:

// initialization of variables
let originalMessage = "gaiusjuliuscaesar";
document.write("Original message: " + originalMessage);
document.write("<br />");

let encryptedMessage = "";
let shift = 1;

// loop through individual characters
for (let i = 0; i < originalMessage.length; i++) {
    let ascii = originalMessage.charCodeAt(i);
    ascii += shift;
    let character = String.fromCharCode(ascii);
    encryptedMessage += character;
}

// message print
document.write("Encrypted message: " + encryptedMessage);

Výstup programu:

Your page
localhost

Program si vyskúšame. Výsledok vyzerá celkom dobre. Skúsme si však zadať vyšší posun alebo napísať slovo zebra. Vidíme, že znaky môžu po z pretiecť do ASCII hodnôt ďalších znakov, v texte teda už nemáme len písmená, ale ďalšie škaredé znaky.

Doplnenie kontroly pretečenia

Problém vyriešime tým, že uzavrieme znaky do kruhu tak, aby posun plynule po znaku z prešiel opäť k znaku a podobne. Postačí nám k tomu jednoduchá podmienka, ktorá od novej ASCII hodnoty odpočíta celú abecedu tak, aby sme začínali opäť na a. Upravený cyklus bude vyzerať takto:

for (let i = 0; i < originalMessage.length; i++) {
    let ascii = originalMessage.charCodeAt(i);
    ascii += shift;
    // Check for overflow
    if (ascii > "z".charCodeAt(0)) {
        ascii -= 26;
    }
    let character = String.fromCharCode(ascii);
    encryptedMessage+= character;
}

Pokiaľ hodnota premennej ascii presiahne ASCII hodnotu z, znížime ju o 26 znakov (toľko znakov má anglická abeceda). Operátor -= vykoná to isté, ako by sme napísali ascii = ascii - 26. Je to jednoduché a náš program je teraz funkčný.

Ako pôvodnú správu nastavíme text zebra a v prehliadači potom program znovu spustíme:

Your page
localhost

Všimnime si, že nikde nepoužívame priame kódy znakov, v podmienke je ascii > "z".charCodeAt(0), aj keď by sme tam mohli napísať rovno 122. Je to z dôvodu, aby bol náš program plne odtienený od explicitných ASCII hodnôt a bolo lepšie viditeľné, ako funguje. Cvične si skúste urobiť dešifrovanie :)

V budúcej lekcii, Textové reťazce v JavaScripte do tretice - Split a join, si ukážeme, že string vie predsa len ešte niečo navyše. Prezradím, že budeme dekódovať Morseovu abecedu.


 

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é 3x (2.79 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Najčastejšie chyby JS nováčikov - Vieš pomenovať premenné?
Všetky články v sekcii
Základné konštrukcie jazyka JavaScript
Preskočiť článok
(neodporúčame)
Textové reťazce v JavaScripte do tretice - Split a join
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
5 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity