ARCHIV |
|||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
Perl (111) - Pokročilá práce se seznamySeznámíme se s několika zajímavými funkcemi, které jsou k dispozici v externích modulech. Zejména se zaměříme na efektivnější práci při operování se seznamem jako celkem, složitější cyklení a na permutování. Když jsme se v minulosti zabývali seznamy, nevyčerpali jsme plně všechny nástroje, které jsou nám k dispozici. Tento díl se to pokusí napravit. Vedle standardních funkcí ze základní distribuce Perlu budeme používat ještě navíc modul Algorithm::Loops. Ten tedy stáhneme z archivu CPAN a nainstalujeme. Skalární operace provedená na pole po složkáchAčkoliv jsme velkou část často používaných funkcí ze základní distribuce Perlu představili v začátku toho seriálu, stále jsme se neseznámili s veledůležitou funkcí map. Ta dokáže vzít pole, na každý jeho prvek aplikovat nějakou funkci a vytvořit tak pole nové. Typickou úlohou pro map je konverze všech prvků seznamu řetězců z malých písmen na velké. Žádná běžná funkce, která by toto řešila neexistuje. Avšak máme zde funkci uc, která je schopna provést změnu velikosti písmen ve skalárním kontextu. Pomocí map ji provedeme po složkách.
Na operaci lze samozřejmě použít i funkci napsanou uživatelem. Příkladem nechť je následující kód, kde funkce map pro každý prvek $_ z pole @cisla vrátí výraz, který vznikne aplikací uvedené funkce na proměnnou $_ (tedy prvek pole @cisla). Do pole @dvojnasobky tedy v našem případě uložíme hodnoty 2, 4, 6, 8, 10, 12, 14, 16, 18, 20.
Jako první argument funkce map lze zadat i samotný výraz z definice funkce zdvojnasob. Následující kód tak docílí téhož, aniž bychom definovali nový podprogram.
Poznamenejme, že v tomto výrazu nemusí $_ vůbec figurovat. Pro vytvoření pole pravdivých hodnot o stejné délce jako původní bychom tedy mohli použít i jeden z následujících příkazů.
Chceme-li zvolit jinou datovou strukturu, do které se mají data ukládat, můžeme udělat jednoduchý trik a nevracet jen skalární hodnotu. Máme-li nějakou množinu klíčů, ke kterým nalezneme hodnoty, budeme je pravděpodobně chtít nějak rozumně uložit - tedy do hashe. V prvním argumentu funkce map tedy pro každý klíč nalezneme hodnotu pomocí nějaké funkce a vrátíme jak tento klíč, tak i záskanou hodnotu. Návod dává tento příkaz.
Poznamenejme, že varianta map používající složené závorky může občas dělat problémy. To proto, že složené závorky mohou indikovat blok i anonymní hash. To, jak se vyhnout problémům je obsáhleji diskutováno v dokumentaci. map však není schopen řešit úplně všechno tak, jak bychom možná na první pohled očekávali. Chceme-li aplikovat na seznam operace tr/// nebo s///, pak je vhodné použít funkci Filter. Funkce map by zde fungovala jinak - zapsala by do nového pole vždy pravdivou nebo nepravdivou hodnotu podle toho, zda došlo k nahrazení. Tak se děje proto, že se fakticky vrací hodnota výrazu ($neco =~ tr///), nikoliv hodnota $neco. Funkce Filter je k dispozici v modulu Algorithm::Loops. Je proto třeba tento modul zavést. Filter se používá podobně jako map. Nikoliv však stejně. Například vyžaduje použití složených závorek. Příkladem je nahrazení všech slov kurs slovem kurz v prvcích pole @texty.
Jiným příkladem je modifikace čtění ze vstupu tak, aby byly ignorovány bílá místa na konci řádků.
Analogie map pro celá poleFunkce MapCar aplikuje danou funkci po složkách na pole polí. Používá se například na práci s maticemi. MapCar příjimá jako parametr anonymní podprogram a seznam odkazů na pole. Tento podprogram je aplikován na pole, která vzniknou seskupením prvních, druhých atd. prvků v předaných seznamech.
Tento příklad vytiskne na výstup následující matici.
Existují další varianty příkazu MapCar. Pro bližší informace nahlédněte do dokumentace. Zde pro představu z dalšího uvedeme jen jeden příklad. Transponovanou matici získáme následujícím příkazem.
Vnořené cyklyCo když potřebujeme vytvořit kód, který bude vypadat nějak takto?
Funkce NestedLoops řeší problém libovolně hlubokého vnoření cyklů do sebe. Uvedenou situaci tak lze vyřešit poměrně elegantně. NestedLoops přijímá tři parametry. Není ale třeba uvádět všechny. Prvním parametrem je odkaz na pole, které obsahuje pro každý cyklus jeden prvek (od vnějšího cyklu po vnitřní). Zde je určeno, přes které hodnoty budeme iterovat. Druhým parametrem je odkaz na hash přepínačů, pomocí kterých se nastavují pokročilejší vlastnosti. Na závěr se udává odkaz na podprogram, který se má provést. Podívejme se na příklad, kde máme dva cykly. Vnější jde od 1 do 2 a vnitřní od 3 do 4. Budeme uvnitř nich tisknout aktuální hodnotu počítadel obou těchto cyklů.
V hashi uvedeném ve druhém parametru můžeme použít zápis OnlyWhen => &test. Takto bude podprogram vykonán pouze tehdy, jsou-li splněny příslušné podmínky (test vrátí pravdivou hodnotu). Podívejme se na toto volání.
Bude mít stejný efekt, jako bychom napsali tento kód.
PermutaceV modulu Algorithm::Loops je též k dispozici několik funkcí pro práci s permutacemi. Permutace pole je obecně nějaké přeuspořádání prvků v poli. Pokud se hodnoty v poli opakují, pak algoritmus, který nalezne všechny možné permutace není vůbec triviální. Pomocí funkcí NextPermute a NextPermuteNum lze toto všechno zařídit velmi pohodlně. Funkce NextPermute (resp. NextPermuteNum pro čísla - rozdíl je v tom, že se shodnost prvků seznamů vyhodnocuje pomocí operátoru == nebo eq) se obvykle používá v podmínce cyklu. Stará se o to, abychom v každé iteraci dostali novou permutaci našeho seznamu. Jakmile projdeme všechny permutace, cyklus skončí, neboť NextPermute vrátí nepravdivou hodnotu. Chceme nyní vypsat všechny permutace prvků 2, 3, 3, 1. Podívejme se na následující příklad.
Výstupem jsou následující řádky.
Na první pohled vidíme, že něco není správně, protože dokonce žádný z řádků nezačína jedničkou. To je proto, že funkce NextPermuteNum požaduje vzestupně setříděný seznam. To může být zdrojem chyb. Příklad totiž musíme upravit.
Jestliže se některá hodnota vyskytuje v seznamu vícekrát, pak teoreticky můžeme dostat stejnou permutaci vícekrát. Funkce NextPermuteNum ji ale vrátí vždy jen jednou. Můžeme se o tom přesvědčit v následujícím příkladu.
Seznam má 4 prvky a tedy máme 4!=4*3*2*1=24 permutací. Avšak jakákoliv permutace aplikovaná na náš seznam dá výsledek 1111. Proto tento kód produkuje jen jediný řádek. Existuje též modul Algorithm::Permute, který umí o něco více a řeší problematiku permutací pomocí objektového rozhraní.
Související články
Předchozí Celou kategorii (seriál) Další
Perl (1) - Dávka teorie na úvod
Perl (2) - Úvod do syntaxe Perl (3) - Proměnné Perl (4) - Čísla a řetězce Perl (5) - Podmínky Perl (6) - Pravdivostní výrazy Perl (7) - Vstup poprvé Perl (8) - Některé základní vestavěné funkce Perl (9) - Cykly Perl (10) - Další řídící struktury Perl (11) - Pole - úvod Perl (12) - Pole - základní operace Perl (13) - Hashe Perl (14) - Další nástroje pro seznamy Perl (15) - Výchozí proměnná, heredoc, symbolické odkazy Perl (16) - Regulární výrazy - začínáme Perl (17) - Regulární výrazy - kotvy Perl (18) - Regulární výrazy - množiny znaků Perl (19) - Regulární výrazy - opakování a kvantifikátory Perl (20) - Regulární výrazy - magické závorky Perl (21) - Regulární výrazy - nahrazování Perl (22) - Regulární výrazy - přepínače Perl (23) - Regulární výrazy - rozšířené vzory Perl (24) - Regulární výrazy - příklady Perl (25) - Regulární výrazy - závěr Perl (26) - Podprogramy Perl (27) - Prototypy Perl (28) - Rozsahy platnosti proměnných Perl (29) - Úvod k práci se soubory Perl (30) - Práce se soubory Perl (31) - Testování souborů Perl (32) - Jiné typy souborů Perl (33) - Formátování výstupu - printf Perl (34) - Formátování výstupu - formáty Perl (35) - Vestavěný debugger Perl (36) - Grafické debuggery Perl (37) - Začínáme s moduly Perl (38) - Rozhraní modulu Perl (39) - Pragma Perl (40) - Dodatky k modulům Perl (41) - CPAN Perl (42) - Argumenty příkazového řádku Perl (43) - Přepínače Perl (44) - Dlouhé přepínače Perl (45) - Odkazy Perl (46) - Užití odkazů a anonymní data Perl (47) - Složitější datové struktury Perl (48) - Libovolně složité datové struktury Perl (49) - Tabulky symbolů a typegloby Perl (50) - Uzávěry a iterátory Perl (51) - Signály Perl (52) - Externí příkazy Perl (53) - Režim nakažení Perl (54) - Fork Perl (55) - Eval Perl (56) - Volby příkazu perl Perl (57) - Jednořádkové skripty Perl (58) - OOP - úvod Perl (59) - OOP - typické použití Perl (60) - OOP - dědičnost Perl (61) - OOP - přínos a užití dědičnosti Perl (62) - OOP - přetěžování Perl (63) - OOP - závěr Perl (64) - Projekt - čtečka sportovních výsledků Perl (65) - Projekt - získání dat Perl (66) - Projekt - výběr zápasů a podrobnosti Perl (67) - Projekt - dokončujeme modul Perl (68) - Projekt - zobrazení zápasů Perl (69) - Projekt - online přenos Perl (70) - Plain Old Documentation Perl (71) - Navazování proměnných Perl (72) - Navazování složitějších datových typů Perl (73) - DBM Perl (74) - Sockety Perl (75) - Obsluha více klientů Perl (76) - Síťová hra v kostky Perl (77) - Služby internetu Perl (78) - Databáze - úvod Perl (79) - Databáze - manipulace s daty Perl (80) - Databáze - závěrečné poznámky Perl (81) - CGI - příprava webového serveru Perl (82) - CGI - první skripty Perl (83) - CGI - získávání dat od uživatele Perl (84) - CGI - usnadnění tvorby skriptů pomocí modulu CGI Perl (85) - CGI - generování dokumentu modulem CGI Perl (86) - CGI - cookies Perl (87) - CGI - příklad aplikace Perl (88) - CGI - závěr Perl (89) - Mason - snadné psaní webů Perl (90) - Mason - speciální bloky Perl (91) - Mason - handlery Perl (92) - Mason - závěr Perl (93) - Catalyst - MVC framework pro Perl Perl (94) - Catalyst - základy pro psaní aplikace Perl (95) - Catalyst - šablony Perl (96) - Catalyst - spolupráce s databází Perl (97) - Curses - tvorba textových uživatelských rozhraní Perl (98) - Curses - pozicování a okna Perl (99) - Curses - měření rychlosti psaní Perl (100) - Curses - použití hotových widgetů Perl (101) - Curses - jednoduchý textový editor Perl (102) - Rozšiřování Perlu pomocí XS Perl (103) - Rozšiřování Perlu pomocí SWIG Perl (104) - Testování rychlosti Perl (105) - Testování programových jednotek Perl (106) - Debugování pomocí komentářů Perl (107) - Moose - moderní objektový systém Perl (108) - Moose - základní vlastnosti Perl (109) - Moose - role Perl (110) - Moose - meta API Perl (112) - Práce s PDF Perl (113) - Práce s archivy Perl (114) - Tk - úvod Perl (115) - Tk - umísťování widgetů Perl (116) - Tk - základní widgety Perl (117) - Tk - některé pokročilejší widgety Perl (118) - Tk - čas a události Perl (119) - Tk - CD man Perl (120) - Wx - základní práce s widgety Perl (121) - Wx - události Perl (122) - Gtk2 - úvod Perl (123) - Gtk2 - základní práce s obrázky Perl (124) - Gtk2 - události a čas Perl (125) - Gtk2 - vlastní widgety Perl (126) - Gtk2 - textové okno a práce s pozicemi Perl (127) - Gtk2 - hierarchické seznamy Perl (128) - Gtk2 - dialogy Perl (129) - Gtk2 - skládání widgetů Perl (130) - Gtk2 - menu a toolbary Perl (131) - Gtk2 - transparentní okna, tray ikona, výběr souborů Perl (132) - Gtk2 - drag&drop, druid Perl (133) - Gtk2 - úpravy vzhledu aplikací pomocí rc Perl (134) - Gtk2 - Glade Interface Designer Perl (135) - XML - čtení a zápis Perl (136) - XML - DOM a SAX přístupy Perl (137) - Vlákna Perl (138) - Memoizace - cachování podprogramů Perl (139) - Profilling - efektivní odhalování pomalých míst v programu Perl (140) - Profilling - píšeme si vlastní profiler / debugger Perl (141) - Formátování kódu, deparsování, perltidy Perl (142) - Způsoby konfigurování Perl (143) - Struktura datových typů, správa paměti Perl (144) - POE - událostmi řízené programování Perl (145) - POE - aplikace typu klient-server Perl (146) - Perl 6 - jazyk budoucnosti Perl (147) - Perl 6 - regulární výrazy, nové operátory Perl (148) - Perl Culture Perl (149) - Závěr Pozvánka na Český Perl Workshop Perl 5.22.0 a vše okolo Perl 5.24.0 a vše okolo Předchozí Celou kategorii (seriál) Další
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera 12.11.2018 21:28 /Redakce Linuxsoft.cz 6.11.2018 2:04 /František Kučera 4.10.2018 21:30 /Ondřej Čečák 18.9.2018 23:30 /František Kučera 9.9.2018 14:15 /Redakce Linuxsoft.cz 12.8.2018 16:58 /František Kučera 16.7.2018 1:05 /František Kučera
Poslední diskuze
31.7.2023 14:13 /
Linda Graham 30.11.2022 9:32 /
Kyle McDermott 13.12.2018 10:57 /
Jan Mareš 2.12.2018 23:56 /
František Kučera 5.10.2018 17:12 /
Jakub Kuljovsky | |||
ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze |