K čemu jsou vlastně dobrá Arrays neboli pole? II. díl - Grafika.cz - vše o počítačové grafice

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Poptávka práce


Webdesign

K čemu jsou vlastně dobrá Arrays neboli pole? II. díl

30. října 2001, 00.00 | Pokračujeme v manipulacích s objekty Array a String, opět postoupíme o kousek dále v pokročilejších skriptovacích technikách. Také se dozvíte, co v AS5 nefunguje...

Pokračujeme v manipulacích s objekty Array a String, opět postoupíme o kousek dále v pokročilejších skriptovacích technikách... a pokud nechcete skončit se skriptováním u akcí typu "gotoAndStop(2)" :o)), tak zjistíte, že s objekty Array se dá mnoho skriptů napsat jednodušeji, rychleji a účinněji. A mimo jiné se dozvíte, jak například roztřídit jednoduchou databázi. A také o tom, co v AS5 nefunguje.

Na konci minulého experimentování s objekty Array a String, které najdete zde, jsem vám slíbil že si užijeme spousty legrace :o))) se speciálními třídícími funkcemi. Budeme pokračovat se souborem, se kterým jsme minule skončili. Pokud se vám podařilo prozřetelně ho smazat nebo pokud byl pro vás předchozí díl tutorialu příliš jednoduchý, můžete si jej stáhnout hotový zde. Všem těm, kteří si potichu (doufám, že potichu :o)) pomyslí jak je moje scéna tedy úplně dočista negraficky nepovedená :o), bych chtěl slíbit, že po skončení tohoto miniseriálu je čeká tutorial, který se bude zabývat problematikou různých menu a dalších navigačních prvků a že tento tutorial bude vypadat k světu i po designerské stránce :o)))

Tak, otevřete si buď soubor, který vám zůstal z minulého dílu, nebo si otevřete ten, který jste si stáhli, a pustíme se do dalších experimentů.

Pro připomenutí: na naší scéně máme v horní části dynamické textové pole, do kterého se vypisuje obsah našeho Array, pod ním je vstupní textové pole, pomocí kterého vkládáme výrazy, vpravo tlačítko pro vkládání do Array, vlevo tlačítko pro další akce.

1. Mazání více elementů pole
V minulém tutoru jsme si ukázali jak smazat položku pole s příslušným indexem, případně s příslušným obsahem. Velmi jednoduše lze také smazat více elementů pole najednou. Funkci "mazani", která je umístěná na prvním framu hlavní časové osy, přepište takto:

function mazani (vyraz) {
konec = parseFloat(vyraz)
manipulacniPole.splice(0, konec)
delete konec
_root.vystup = ""
for (i=0;i<manipulacniPole.length;i++) {
_root.vystup = _root.vystup + manipulacniPole[i] + newline
}
}

Metoda "splice", použitá na druhém řádku funkce, smaže položky pole metodou "od-do". První parametr (v našem případě je to "0") udává startovní index pro mazání, druhý parametr (v našem případě to, co napíšeme do vstupního textového pole, přenášené pomocí proměnné "konec") udává počet položek, které budou smazány.

Proveďte si pokus s touto funkcí. Pomocí vstupního tlačítka a vstupního textového pole si naplňte naše Array "manipulační pole" například takto:

[a, b, c, d, e, f]

takže naše výstupní textové pole nám vypíše:

a
b
c
d
e

Nyní zadejte do vstupního textového pole hodnotu 3. Tím se nám smaží položky pole od nulté po druhou a naše výstupní pole by mělo vypadat takto:

d e

2. Složitější třídící funkce
Jistě vás už napadlo: pokud jsou položkami v poli například jména, načtená z nějaké jednoduché (třeba jen textové) databáze, jak je setřídím podle příjmení, když všechna jména začínají křestním jménem? To nám přeci jednoduché třídění, o kterém jsme mluvili v minulém tutorialu, neumožňuje.

K takovému složitějšímu třídění jsou v AS k dispozici tzv. třídící funkce. Z minulého tutorialu si jistě pamatujete jednoduché třídění se syntaxí:

nejakePole.sort()

Tato syntaxe obsahuje jako volitelný parametr volání třídící funkce:

nejakePole.sort(tridiciFunkce)

a tuto třídící funkci si můžeme nadefinovat naprosto libovolně. Podívejme se na příklad takové třídící funkce, která dokáže setřídit jména ve formátu "Křestní jméno - Příjmení" podle příjmení.

Jak taková třídící funkce vlastně pracuje? Její logika je velmi jednoduchá. Třídící funkce vlastně říká: "vezmi dva prvky "a" a "b" a podle daných kritérií rozhodni, který z nich bude považován na 'větší' a který za 'menší', tj. který z nich bude po seřazení na prvním místě a který na druhém".

Tuto informaci předává třídící funkce do metody "sort" tak, že odešle (vrátí) číslo:

  • "1" znamená, že prvek "a" bude v pořadí za prvkem "b"
  • "-1" znamená, že prvek "a" bude před prvkem "b"
  • "0" znamená, že prvky jsou shodné

No, zní to možná složitě, podívejme se raději na jednoduchý příklad.

Řekněme, že naše třídící funkce vypadá takto:

function setridit (a, b) {
if (a < b) {return -1}
if (a == b) {return 0}
if (a > b) {return 1}
}

Nyní zavoláme funkci s parametry "5" a "8", tedy a=5, b=8. Funkce vyhodnotí, že "a je menší než b", je tedy splněná podmínka na prvním řádku funkce a vrátí se nám hodnota "-1". Metoda "sort" potom pomocí takového algoritmu porovná mezi sebou jednotlivé položky pole a podle vracených jedniček, mínus jedniček a nul z třídící funkce pole seřadí.

Takže nyní si do prvního snímku hlavní časové osy přidáme následující třídící funkci:

function setridit (a,b) {
var polohaMezery1 = a.indexOf(" ")
var polohaMezery2 = b.indexOf(" ")
var prijmeni1 = a.substr(polohaMezery1)
var prijmeni2 = b.substr(polohaMezery2)
if (prijmeni1 < prijmeni2) {return -1}
if (prijmeni1 == prijmeni2) {return 0}
if (prijmeni1 > prijmeni2) {return 1}
}

Tato funkce na prvních dvou řádcích nejprve zjistí, na kterém místě ve Jméně je mezera (mezera odděluje od sebe Křestní jméno a Příjmení). Na dalších dvou řádcích se pomocí metody "substr" oddělí Křestní jméno od Příjmení, zůstane nám pouze Příjmení. A tato příjmení pak další tři řádky porovnají. Jak prosté a jednoduché...

Na tlačítko, kterým jsme doposud volali mazací funkci, nyní vložíme tyto skripty:

on (release) {
_root.manipulacniPole.sort(_root.setridit)
_root.vystup = ""
for (i=0;i<manipulacniPole.length;i++) {
_root.vystup = _root.vystup + manipulacniPole[i] + newline
}
}

První řádek skriptu volá třídění našeho manipulačního pole pomocí třídící funkce, kterou jsme před chvílí napsali. Další tři řádky už jen vypíší aktualizovaný obsah do výstupního textového pole.

Pokud se vám podařilo vše zapsat správně, zkuste si následující příklad. Nejprve vložte pomocí vstupního textového pole a vkládacího tlačítka například toto:

Mirek Pusin
Jarka Metelda
Jindra Hujer
Rychly Nozka

a stiskněte tlačítko s akcí setřídění. Nyní by měl vypadat text ve výstupním textovém okně takto:

Jindra Hujer
Jarka Metelda
Rychly Nozka
Mirek Pusin
*(podobnost se jmény jistých neexistujících osob je čistě náhodná :o)

Pokud porozumíte tomuto jednoduchému příkladu třídící funkce, budete bez problémů schopní napsat jakoukoliv třídící funkci.

3. Roztřídění jednoduché databáze
Pokud se někdo z vás zabýval problémem jak dostat do Flashe jednoduchou (nebo i složitější) databázi a co si s ní potom počít, pravděpodobně jste zjistili následující: není problém načíst do Flashe proměnné např. z PHP skriptu:

loadVariables("base.php")

nebo týmž skriptem odeslat proměnné do serverside skriptu, nechat je vyhodnotit a načíst po vyhodnocení nové hodnoty. Stejně tak je velmi jednoduché načíst externí textový soubor.

Problém nastává ve chvíli, kdy je třeba pracovat s načtenými proměnnými. Pokud jich je mnoho, může se stát, že je skript ve Flashi příliš složitý, případně se nám vrátí proměnné, u nichž neznáme jejich jméno a tudíž je budeme těžko zpracovávat....

Jednou z možností je provést jednoduché zpracování ve Flashi. Je však potřeba dobře rozvážit, kdy je tato cesta pro nás vhodná a kdy ne.

Na jedné straně stojí možnost jednoduchého zápisu proměnných a vcelku jednoduchého třídění ve Flashi, na druhé straně fakt, že AS je opravdu pomalý a od určitých objemů dat skoro nepoužitelný.

Ale zanechme teorie, pro mnoho z vás bude jistě snadnější občas použít lenivý AS a jednoduchý textový soubor namísto serverside skriptu, který také nemusí na všech serverech pracovat. Podívejme se na takový jednoduchý případ.

Řekněme, že se nám podařilo z externího textového souboru načíst proměnnou "topScores" takto:

topScores = "Franta Bedna:300^Petr Rychlik:800^DavidNestihal:200^Jindrich Lenivy:50^Pepa Levy:10^Big Machirek:1700"

Zapište si takto tuto proměnnou na první frame hlavní časové osy v našem pokusném souboru.

A za ní si napíšeme třídící funkci. Jak to uděláme, abychom jednoduchý string "topScores" rozdělili na jednotlivé řádky se jmény a setřídili je podle skóre? Takto:

  1. rozdělíme proměnnou "topScores"na jednotlivé položky podle oddělovače "^"
  2. tyto položky zapíšeme jako jednotlivé elementy pole
  3. toto pole potom setřídíme třídící funkcí podle skóre

AS nám tentokrát opravdu vyjde vstříc, protože nám umožní udělat kroky 1) a 2) najednou:

poleTopScores = topScores.split("^")

Tento skript vložíme jako další řádek pod zápis proměnné "topScores". Metoda "split" prohledá textový řetězec a tam, kde najde delimiter (oddělovač), "odsekne" kus mezi dvěma delimitery a vytvoří z něj novou položku v Array.

Teď už zbývá jen napsat třídící funkci:

function setridit (a,b) {
var poloha1 = a.indexOf(":")
var poloha2 = b.indexOf(":")
var body1 = parseFloat(a.substr(poloha1 + 1))
var body2 = parseFloat(b.substr(poloha2 + 1))
if (body1 < body2) {return -1}
if (body1 == body2) {return 0}
if (body1 > body2) {return 1}
}

Jak vidíte, je tato funkce velmi podobná té naší předchozí, pouze jsme přidali funkci "parseFloat", která převádí textový řetězec na číslo.

A můžeme dopsat i zbytek skriptu:

poleTopScores.sort(setridit)
poleTopScores.reverse()
_root.vystup = ""
for (i=0;i<poleTopScores.length;i++) {
_root.vystup = _root.vystup + poleTopScores[i] + newline
}

Pokud chcete například udělat jednoduchou on-line gamesku, můžete použít takovéto třídění a pomocí "loadVariables" odesílat a přijímat proměnné do jednoduchého serverside skriptu, který bude zapisovat skóre. Nebo můžete třídit novinky z externího textového souboru podle data....

4. AJ VAJ aneb bohužel, ač se to píše v manuálu, nefunguje to
Ti, kteří už mají pár zkušeností s AS, případně se vyznají v jiném programovacím jazyce, jsou si určitě vědomí, že manipulace s objekty typu Array a String poskytují mnoho možností pro psaní relativně velmi jednoduchých a velmi účinných skriptů.

Ale aby nám vývojáři AS přeci jen trochu pokazili radost, vmontovali nám do něj nepěknou chybu.

Uveďme si jí na příkladě. Mám například textový řetězec "Umba Uga" a chci udělat animaci, ve které bude přilétávat pímeno po písmeni. A navíc chci, abych mohl do tohoto řetězce zapsat cokoliv a animace fungovala stále stejně. A aby se v ní daly prohazovat pozice písmen.... a třídit dle abecedy....

Udělat tento typ animace s pomocí dynamických textových polí je opravdu jednoduché. První, co vás po dnešním tutiku napadne, je: no jasně, vezmu ten textový řetězec, pomocí metody "split" ho převedu do Array.... jasně, vždyť je to jednoduché, akorát potřebuji udělat "split" tak, aby každá položka pole byla jedno písmeno.... no, podívám se do manuálu.... a to je také jednoduché, tam píší, že když je jako delimiter (oddělovač) uvedený prázdný textový řetězec, tak se to provede přesně tak, jak chci.... a UAAAAAA, mě to NEFUNGUJE!!!!

Přesně tento problém jsem řešil a zběsile jsem hodinu hledal ve své skriptu chybu. Patřím k těm intuitivně založeným skriptařům, kteří velmi rychle napíší kostru skriptu a postupně dolaďují jednotlivé řádky a přivádějí je životu (takže mě nepřekvapí, když mi něco napoprvé nechodí).... ale tady se mi to nepovedlo rozchodit....

Odpověď je jednoduchá: Macromedia kvůli tomu, aby dosáhla kýžené kompatibility s normou ECMA-262, zařadila do manuálu "dělení textového řetězce pomocí prázdného textového řetězce jako delimiteru", ale zapomněla nám to naprogramovat.

Takže se s tím zbytečně nedřete a až narazíte na tento problém, vězte, že je neřešitelný a musíte ho řešit jinak (přes smyčku) (myslím programovou, ne tu konopnou :o)).

Musím říct, že narozdíl od slečen, které člověk může mít rád právě pro jejich chyby (někdy je to milé :o), Flash se musí člověk naučit mít rád i přes jeho chyby a někdy je to nelehké....

Proto si v příštím tutorialu řekneme, jak můžeme vyřešit jednu z takových drobných vad na kráse AS, kterou je naprosto neúměrně pomalé provádění některých operací s objektem String, a to přepsáním jeho "generické" vlastnosti.

Tématické zařazení:

 » Rubriky  » Go verze  

 » Rubriky  » Webdesign  

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: