V dnešním díle si přiblížíme další z datových struktur a to pole.
21.12.2004 15:00 | Josef "jose" Kadlec | přečteno 11081×
Pole je jedna z tzv. seznamová struktura, kam patří společně se strukturou hash. Pole je tedy seznam skalárních dat, které jsou seřazené od prvního do posledního prvku. Jak už jsem zmínil v některém z minulých dílů, pole poznáme tak, že jeho názvu předchází znak "@". Pro název samozřejmě platí skoro všechna pravidla tvorby názvů proměnných - tzn. že se rozlišují velká a malá písmena, maximální délka názvu je 255 znaků, ale je tu jeden rozdíl! Názvy polí mohou totiž mohou začínat číslicí. Platí pak také samozřejmě, že názvy polí a jiných proměnných mezi sebou nekolidují. K prvkům pole se přistupuje pomocí indexů prvků pole, což souvisí právě s tím, že pole jsou řazená.
A nyní se podíváme na to, jak mohou taková pole vypadat a jak se tvoří. Nejprve si vytvoříme prázdné pole:
@pole = ();
Teď si vytvoříme jednoduchá pole se skalárními daty:
@pole = (1,
2, 3, 4,
5); #pole s
cisly
@pole = ('Pepa', 'Karel', 'Vojta'); #pole retezcu
@pole = (1,
'Pepa', 5+1, $var); #smisene pole
K jednoduššímu zápisu pole lze použít i příkazu qw
a to takto:
@pole = qw(
Po Ut St Ct
Pa So Ne
);
Vidíme, že si vůbec nemusíme dávat práci s psaním oddělovacího znaku čárka a uvozovek.
Pole lze i vnořovat do sebe - tzn. pokud některými (nebo všemi) prvky pole jsou další pole. Ovšem nemusí to mít logický význam pro programátora, protože tato pole se sloučí do jednoho.
K prvkům pole se přistupuje pomocí indexu, který určuje pozici elementu v poli, přičemž pole jsou indexována od nuly. Takže když budu chtít například uložit řetězec "Vojta" do prvního prvku pole, udělám to takto:
$pole[0] = "Vojta";
Všimněme si, že tato proměnná nemá před názvem znak "@", ale přesto nemá s proměnnou $pole nic společného.
Pole je dynamické jako všechny proměnné v Perlu, takže nemusíte, jako například v programovacím jazyce C, určovat délku pole v deklaraci. Takže když máte například pole o pěti prvcích (tzn. do prvku s indexem 4, protože se indexuje od 0) a chcete přidat další prvek, tak to uděláte prostě takto:
$pole[5] = "dalsi sesty prvek pole";
Pokud se budeme snažit přidat prvek, který nenásleduje za poslední definovaný prvek a přidali by jste prvek v našem poli o šesti prvcích například na desátou pozici, tak budou chybějící prvky mezi těmito prvky vyplněný nedefinovými hodnotami. Hodnoty indexů mohou mít i zápornou hodnotu. Takové indexy se pak počítají od konce pole, takže například prvek s indexem -1 je poslední prvek.
Pokud chceme procházet pole v cyklu, tak je nejjednodušší a nejefektivnější použít cyklus
foreach
, jak už jsme si popsali v díle o cyklech. Pokud ale potřebujete použít pro
zpracování pole cyklus while či for, tak potřebujete i znát index posledního prvku pole, abyste
věděli, kdy má cyklus skončit. Index posledního prvku pole je uložen v proměnné $#pole
.
Skutečná délka pole - tzn. počet prvků v poli je uložená přímo v proměnné @pole. Takže když budete
chtít uložit délku pole @pole do proměnné $delka_pole, tak to uděláte takto:
$delka_pole = @pole;
Je ovšem potřeba si dávat pozor na kontext, podle kterého data přiřazujeme.
Co když budete potřebovat vytvořit pole s posloupností čísel od 1 do 100. Asi těžko vypíšete každý prvek zvlášť. Můžete použít buď cyklu a nebo elegantnější zápisu:
@pole = (1
.. 100);
Funguje to i se znaky, takže znaky od "e" do "k" v abecedě vypíšete takto:
@pole = ('e'
.. 'k');
Nad výpisem pole například na standardní výstup asi nemusíte přemýšlet a použijete prostě cyklus for s přístupem k prvkům přes indexy nebo cyklus foreach, ale existuje jedna elegantnější cesta, jak vytisknout pole (nebo zpracovávat jeho prvky).
print "@pole\n";
Všimněme si, že proměnná pole je v uvozovkách. Tento příkaz vypíše všechny prvky pole a to každý na jeden řádek.
Nyní si představíme funkce, které se typicky používají pro práci s poli. Pokud budeme chtít do pole přidat prvek (z pravé strany), tak bychom mohli použít něco podobného jako:
@pole = (@pole, $novy_element);
Zde je důležizé si dávat pozor na kontext přiřazení (viz. níže). K přidání dalšího prvku z pravé strany pole lze použít i funkci push
takto:
push(@pole, $novy_element);
Touto funkcí je možné přiřazovat i více prvků najednou a to takto:
@pole = (1,2,3);
push(@pole,4,5,6);
Tímto jsme vytvořili pole o šesti prvcích, které představují posloupnost čísel od 1 do 6. Další užitečnou funkcí je funkce pop
, která naopak prvky z pole odebírá (zase důležité upozornit, že z pravé strany pole - neboli od konce). Takže použití může vypadat takto:
$posledni_element = pop(@pole);
Poslední prvek z pole @pole
se odebere a uloží do proměnné $posledni_element
. Další funkce unshift
a shift
dělají obdobnou operaci, s tím rozdílem, že z levé strany pole - čili ze začátku pole. Příklad použití:
unshift(@fred, $novy_prvek); #prida prvek $a na zacatek pole
unshift(@fred, 1, 2, 3); #prida prvky 1, 2, 3 na zacatek pole
$posledni_prvek = shift(@pole); #odstrani prvni prvek z pole a ulozi ho do promenne $posledni_prvek
Další užitečnou funkcí je funkce reverse
, která vrátí pole s obráceným pořadím prvků. Použití je prosté:
@pole = (1, 2, 3);
@pole = reverse(@pole); #pole nyni obsahuje prvky (3, 2, 1)
Mezi další funkce, které lze použít přímo s poli patří například funce sort
, která vám seřadí prvky v poli od nejmenšího po největší (popř. u řetězců podle abecedy) a nebo například funkce chomp
, která odstraní z konce každého prvku znaky nové řádky.
Nakonec si něco řekneme o kontextu přiřazení. Nejdříve se podíváme na pár příkladů přířazení, abychom viděli, jak se chovají:
($a, $b, $c) = (1, 2, 3); #priradi jednotlive prvky do jednotlivych prvku pole
($x, @pole) = ($a, $b, $c); #$a priradi do $x a $b, $c do @pole
($x, @pole) = @pole; #do $x priradi prvni prvek z @pole a @pole bude bez tohoto prvku
Co když ale zapíši takovéto dva zápisy:
$x = @pole;
($x) = @pole;
V prvním případě bude do proměnné $x
uložen počet prvků pole. Zatímco v druhém případě bude do $x
uložen první prvek pole. Proto je potřeba si dávat na kontext, ve kterém se chceme pohybovat.
V přístím díle se popereme s hashi.