LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (48) - Libovolně složité datové struktury

Ukážeme si příklady datových struktur, které lze použít k ukládání dat se složitými vzájemnými vztahy. Popíšeme také způsob prohlížení těchto struktur vhodný pro ladění.

18.12.2006 06:00 | Jiří Václavík | Články autora | přečteno 14887×

Dvojrozměrné struktury, kteréžto byly tématem minulého dílu, jsou mezistupněm k rozsáhlým datovým stromům. Ty poskytují způsob, kterým se lze poměrně snadno vypořádat se složitými vztahy mezi daty. Složité datové struktury mohou být vytvořeny například jako dlouhý propojený řetězec odkazů a až daleko na jeho konci jsou skalární hodnoty - tedy ta konkrétní data, kvůli kterým celá struktura existuje. Odkazy budou jsou v datové struktuře pouze proto, aby vytvořily v té změti dat nějaký systém.

Protože teorii již máme v podstatě kompletně zvládnutou, ukážeme si příklad. Vytvoříme si datovou strukturu, která bude reprezentovat atlas světa. To je velice názorný příklad. Právě atlas totiž obsahuje data setříděná postupně podle řady kritérií, tedy přesně to, na co chceme ukázat.

Nejprve se musíme rozhodnout, která data budeme uchovávat. Rozhodněme se pro informace o jednotlivých státech světa. Každý stát bude zařazen do nějaké části světa (Evropa, Asie apod.). Samotné informace budou obsahovat rozlohu, počet obyvatel, jméno hlavního města a seznam jmen dalších větších měst.

Vše budeme řešit pomocí anonymních dat. Budeme mít jedinou pojmenovanou proměnnou. Pomocí ní musíme být schopni vytisknout jakoukoliv informaci, obsaženou v naší datové struktuře.

Začneme tím, že vytvoříme hash nejvyšší úrovně. Jeho prvky budou tvořeny dvojicí hodnot - klíčem bude jméno části světa a prvkem odkaz na hash, ve kterém bude seznam států.

%svet = (
    "evropa" => { ... },
    "asie" => { ... },
    "jizni amerika" => { ... },
    "severni amerika" => { ... },
    "australie" => { ... },
    "antarktida" => { ... },
    "afrika" => { ... }

Jak už bylo řečeno, v každém z těchto anonymních hashů bude seznam států.

%svet = (
    "evropa" => {
        "albanie" => { ... },
        "andorra" => { ... },
        "belgie" => { ... },
        "belorusko" => { ... },
        "bosna" => { ... },
        ...
    },
    ...
);

Každá hodnota prvku je opět odkazem na hash. Tento hash už bude obsahovat konkrétní informace.

%svet = (
    "evropa" => {
          ...
        "ceska republika" => {
            "rozloha" => 79_000,
            "lidi" => 10_250_000,
            "hlavni mesto" => "Praha",
            "dalsi mesta" => [ ... ]
        },
        ...
    },
    ...
);

Vnoření ale půjde ještě hlouběji. Do prvku s klíčem "dalsi mesta" přiřadíme odkaz na seznam měst.

%svet = (
    "evropa" => {
        "ceska republika" => {
            "rozloha" => 79_000,
            "lidi" => 10_250_000,
            "hlavni mesto" => "Praha",
            "dalsi mesta" => [
                "Brno",
                "Ostrava",
                "Ceske Budejovice",
                "Plzen"
            ]
        },
        ...
    },
    ...
);

A tak můžeme pokračovat dále. Ke všemu bychom stále přistupovali pomocí jediné proměnné. Otázka je, jak moc by byl další postup vhodný. Struktura by teoreticky mohla obsahovat například ještě informace o jednotlivých městech apod. Avšak je třeba se s tímto umět ve vhodnou chvíli zastavit a zamyslet se, zda by nebylo lepší řešit problém nějak jinak. Leckdo by namítl, že ani námi demonstrovanou strukturu by přes hash neřešil. V mnoha případech bude například než struktura vhodnější databáze, které si podrobně rozebereme někdy v budoucnu.

Teď již ale zabíháme někam úplně jinam. Smysl předchozího odstavce měl být ten, že rozsáhlou datovou strukturu je dobré použít, pokud je to "rozumné". To znamená, že s dobře navrženou datovou strukturou by se mělo nechat pohodlně pracovat a měla by obsahovat opravdu jen ty informace, pro které je určena. Do jisté míry také záleží na zkušenostech a vkusu programátora.

Tak čí onak, metoda vytváření struktury by měla být z výše uvedeného již jasná. Nyní se krátce podívejme, jak se s takovou strukturou pracuje.

Kontinenty jsou klíči proměnné %svet. Použijeme funkci keys k jejich vytisknutí.

print "Seznam kontinentu: ", keys %svet;

Půjdeme o úroveň dále a vytiskneme seznam evropských států. Na tento seznam ukazuje proměnná $svet{"evropa"}.

print "Seznam evropskych statu: ", keys %{$svet{"evropa"}};

Teď zkusíme nějaký konkrétní údaj.

print "Rozloha Ceske republiky je ", $svet{"evropa"}{"ceska republika"}{"rozloha"};

S těmito údaji lze operovat stejně jako s jakoukoliv jinou skalární hodnotou. Poměr počtu lidí České repuliky k její rozloze získáme takto.

print "Pomer poctu lidi Ceske republiky k jeji rozloze je ", $svet{"evropa"}{"ceska republika"}{"lidi"} / $svet{"evropa"}{"ceska republika"}{"rozloha"};

Dále vypíšeme seznam měst České republiky. Nesmíme zapomenout, že Praha jako hlavní město je ve zvláštním prvku. Dále musíme myslet na to, že když tiskneme ostatní města, jde o seznam, a tudíž musíme použít jako předponu zavináč.

print "Mesta Ceske republiky: ", $svet{"evropa"}{"ceska republika"}{"hlavni mesto"},
@{$svet{"evropa"}{"ceska republika"}{"dalsi mesta"}};

Teď uděláme podobnou věc, ale vytiskneme hned všechna evropská města, která máme zaznamenaná. Použijeme cyklus foreach a v každé jeho iteraci přiřadíme do promněnné $_ jeden odkaz na hash obsahující informace o konkrétním evropském státě. Tento odkaz v tělě cyklu dereferencujeme. Všimněme si, jak je odkaz dereferencován. Je totiž větví celé struktury %svet. Název státu nás nezajímá, proto můžeme použít pro vytvoření pole předávaného cyklu funkci values.

print "Seznam evropskych mest: ";
foreach (values %{$svet{"evropa"}}){
    print $_->{"hlavni mesto"};  #tiskne hlavní město
    print @{$_->{"dalsi mesta"}};#tiskne další města
}

Poslední příklad vylepšíme a budeme tisknout i název státu, ve kterém města leží. V předchozím příkladu nás název státu nezajímal. Teď už ale ano. Protože název státu uložen jako klíč hashe, musíme změnit pole předávané cyklu foreach. values vyměníme za keys. Teď už $_ nebude přímo odkazem na hash s informacemi o konkrétním státě, ale pouze řetězec obsahující název státu. Musíme proto dereferencovat už od nejvyšší úrovně proměnné %svet.

print "Seznam evropskych mest podle statu: ";
foreach (keys %{$svet{"evropa"}}){
    print "$_: ";                               #tiskne název státu
    print $svet{"evropa"}{$_}{"hlavni mesto"};  #tiskne hlavní město
    print @{$svet{"evropa"}{$_}{"dalsi mesta"}};#tiskne další města
    print "\n";
}

Nejen získávat je třeba informace. Je nutné občas aktualizovat - přidávat, mazat nebo editovat. Občas vypukne válka a nějaké státy zanikají a jiné vznikají. Přidáme si tedy nový stát.

$svet{"evropa"}{"novy stat"} = {
    "rozloha" => 10_000,
    "lidi" => 1_000_000,
    "hlavni mesto" => "mesto X",
    "dalsi mesta" => [
        "mesto A",
        "mesto B"
    ]
};

Funkcí delete můžeme prvky datových struktur naopak mazat.

Moduly pro manipulaci s datovými strukturami

Nyní si představíme moduly Storable a Data::Dumper.

Tisk datových struktur

Modul Data::Dumper se používá k formátovanému tisku datových struktur. Obsahuje funkci Dumper, která přijímá jako parametr odkaz na datovou strukturu a tu zformátovanou tiskne na výstup.

use Data::Dumper;
print Dumper $odkaz;

V případě datové struktury podobné té, kterou jsme si dnes napsali, se vytiskne toto.

  $ perl dumper.pl
  $VAR1 = {
          'evropa' => {
                        'ceska republika' => {
                                               'lidi' => 10250000,
                                               'dalsi mesta' => [
                                                                  'Brno',
                                                                  'Ostrava',
                                                                  'Ceske Budejovice',
                                                                  'Plzen'
                                                                ],
                                               'rozloha' => 79000,
                                               'hlavni mesto' => 'Praha'
                                             },
                        ...
                      },
          'asie' => {}
          ...
        };
  $

Zapamatujme si, že je nutné, abychom opravdu předali odkaz. Svět na tom sice nestojí, ale je dobré to mít na paměti, když nám Dumper nevypíše to, co chceme. Může to svádět psát pouze

print Dumper %svet;

Takhle se vytiskne něco trochu jiného. Dumper ve skutečnosti přijímá seznam odkazů, takže by se vytiskly struktury pro každý klíč i hodnotu. Dumper musí být volána takto.

print Dumper \%svet;

Perzistence datových struktur

Modul Storable zajišťuje perzistenci. Používá se k ukládání datových struktur do souborů a zpětně i k jejich načítání.

K uložení se používá funkce store. Umožňuje uložit do souboru jednu datovou strukturu. (Pokud jich chceme uložit více, můžeme předávat odkaz na pole odkazů na datové struktury.)

use Storable;
store(\%odkaz, "soubor");

store ukládá data do souboru v binární podobě.

Pro načtení ze souboru slouží funkce retrieve. Znovuvytvoří strukturu a vrátí na ní odkaz.

use Storable;
$r_svet = retrieve("soubor");

Storable nabízí ještě funkce dclone, která klonuje (nikoliv vytváří odkaz na ni!) datovou strukturu. Přesnou kopii tak můžeme získat tímto způsobem.

use Storable;
$r_kopie_svet = Storable::dclone(\%svet);

Následujícím trikem danou strukturu hned i pojmenujeme.

%kopie_svet = %{ Storable::dclone(\%svet) };

To bylo stručné, avšak pro běžné účely dostačující seznámení s moduly Storable a Data::Dumper. Zájemci naleznou podrobnější informace v dokumentaci.

Pseudohashe

Na závěr uveďme, opět spíše pro zajímavost, něco o pseudohashích. Pseudohash je speciální datová struktura, se kterou lze pracovat jako s odkazem na pole i jako odkazem na hash. V Perlu je zavedena pouze experimentálně.

Pseudohash je pole, jehož první prvek musí být odkaz na hash. V něm jsou řetězce, které dávají do vztahu indexy pole s klíči hashe.

$pseudohash = [{"a" => 1, "b" => 2, "c" => 3}, "1. hodnota", "2. hodnota", "3. hodnota"];

Nyní lze k hodnotám přistupovat jako k hodnotám hashe nebo hodnotám pole. Tyto zápisy vytisknou stejnou hodnotu.

print $pseudohash->{"c"};
print $pseudohash->[3];

Více o pseudohashích na perlref(1).

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

14.11.2017 16:56 /František Kučera

Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tradičně první čtvrtek před třetím pátkem v měsíci: 16. listopadu od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).


Přidat komentář

12.11.2017 11:06 /Redakce Linuxsoft.cz
PR: 4. ročník odborné IT konference na téma Datová centra pro business proběhne již ve čtvrtek 23. listopadu 2017 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00. Konference o návrhu, budování, správě a efektivním využívání datových center nabídne odpovědi na aktuální a často řešené otázky, např Jaké jsou aktuální trendy v oblasti datových center a jak je využít pro vlastní prospěch? Jak zajistit pro firmu či jinou organizaci odpovídající služby datových center? Podle jakých kritérií vybrat dodavatele služeb? Jak volit součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně spravovat datové centrum? Jak eliminovat možná rizika? apod.
Přidat komentář

13.9.2017 8:00 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tentokrát netradičně v pondělí: 18. září od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

3.9.2017 20:45 /Redakce Linuxsoft.cz
PR: Dne 21. září 2017 proběhne v Praze konference "Mobilní řešení pro business". Hlavní tématy konference budou: nejnovější trendy v oblasti mobilních řešení pro firmy, efektivní využití mobilních zařízení, bezpečnostní rizika a řešení pro jejich omezení, správa mobilních zařízení ve firmách a další.
Přidat komentář

15.5.2017 23:50 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

18.9.2017 14:37 / Rojas
high security vault

15.9.2017 7:33 / Wilson
new zealand childcare jobs

31.8.2017 12:11 / Jaromir Obr
Re: ukůládání dat ze souboru

30.7.2017 11:12 / Jaromir Obr
Národní znaky

27.7.2017 12:24 / Jaromir Obr
Cteni/zapis

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze