Práce s tabulky
Pokud zvládnete tabulky, pak jste na dobré cestÄ› zvládnout celý jazyk. Jedna z poslednÃch základnÃch vÄ›cà co zbývá vysvÄ›tlit jsou právÄ› tabulky. Nechal jsem si je na konec, protože v nich uplatnÃme téměř vÅ¡e co jsme se nauÄili. K ovládánà tabulek nám sloužà také tÅ™Ãda table.
Základnà logika tabulek
Tabulka je nehomogennà struktura dat. Znamená to, že data v nà nejsou stejného datového typu. Můžeme tak mÃt na stejné úrovni. K jednotlivým úrovnÃm tabulky pÅ™istupujeme pÅ™es tzv. indexy. Index může být zapsán jako text za teÄnou u názvu tabulky, a nebo jako ÄÃslo v hranatých ([]) závorkách. Lua indexuje položky od jedniÄky - to znamená, že pokud bude tabulka automaticky vygenerována, jejà prvnà index bude 1. Tabulku deklarujeme (uvedeme) tak, že do nà pÅ™iÅ™adÃme hodnotu {}.
PÅ™Ãklad:
1local tabulka = {};2-- ukazka txt indexu - chovaji se jako obyc.3-- promenne jen jsou v tabulce4tabulka.index1 = 5;5tabulka.index2 = 1.86464;6tabulka.index3 = "Ahoj";7-- ukazka ciselneho indexu8tabulka[1] = "Ahoj";9tabulka[2] = 64;10-- vytvoreni tabulky v tabulce11tabulka[3] = {};12tabulka[3].index1 = 6;1314-- vypsani hodnot15for _,v in pairs(tabulka) do16 print(v);17end;18--[[19 LOG:20 "Ahoj21 64.00000022 5.00000023 Ahoj24 1.86464025 "26]]--
Z pÅ™Ãkladu lze vidÄ›t, jak se zapisujà textové indexy. VidÃme zde také pÅ™Ãklad procházenà pole pomocà ipairs. V logu budeme mÃt jeden řádek prázdný - nemůžeme vytisknou pole a tak se vytiskne nic.
Objekty
Objekty jsem zaÅ™adil pod tabulky proto, protože se v tabulkách vytvářejÃ. Objekt nenà nic jiného než soubor funkcà v tabulce. Jeden velký obejkt použÃváme neustále - náš skript. Objekt může obsahovat funkce, promÄ›nné atd...
Ukázka jednoduché tÅ™Ãdy pÅ™es tabulku:
12-- Objekt skriptu - vytvoreni tabulky pro objekt3-- Hra pri inicializaci doplni zbytek4-- u nasich trid si to musime udelat sami5mujSkript = {};67function mujSkript.prerequisitesPresent(specializations)8 return true;9end;1011function mujSkript:load(xmlFile)12 local promenna = MyClass.new(5);13 print(promenna:get_value());14 -- "5"15end;1617function mujSkript:mouseEvent(posX, posY, isDown, isUp, button)18end;1920function mujSkript:keyEvent(unicode, sym, modifier, idDown)21end;2223function mujSkript:update(dt)24end;2526function mujSkript:updateTick(dt)27end;2829function mujSkript:draw()30end;3132-- Objekt muj vytvoreny33-- K podrobnejsimu rozpisu objektu se dostaneme pozdeji34MyClass = {};35MyClass.__index = MyClass;3637function MyClass.new(init)38 local self = setmetatable({}, MyClass);39 self.value = init;40 return self;41end;4243function MyClass.set_value(self, newval)44 self.value = newval;45end;4647function MyClass.get_value(self)48 return self.value;49end;50
K podrobnÄ›jÅ¡Ãmu rozpisu objektů se dostaneme o hodnÄ› pozdÄ›ji - ale dostaneme se k nim. Toto byla ukázka jednoduchého objektu.
VÃcesložková tabulka
Pro nÄ›koho je to velká obtÞ, ale vÄ›du v tom nehledejte. Je to jen pole v poli. Můžeme mÃt tÅ™eba sedmisložkové pole. Sami poznáte, že je budete velmi využÃvat. Jako pÅ™Ãklad uvedu seznam položek v obchodÄ›, který si vypÃÅ¡eme:
1local obchod = {};2obchod.info = {};3obchod.info.ulice = "Kratochvilova";4obchod.info.cp = "7/1490";5obchod.info.mesto = "Ostrava - Moravska Ostrava";6obchod.info.kraj = "Moravskoslezsky";7obchod.info.zeme = "CR";8obchod.nabidka = {};9obchod.nabidka[1] = {};10obchod.nabidka[1].cena = 5000;11obchod.nabidka[1].nazev = "Bonbony";12obchod.nabidka[1].dostupnost = "Ihned";13obchod.nabidka[2] = {};14obchod.nabidka[2].cena = 1000;15obchod.nabidka[2].nazev = "Ubytovani";16obchod.nabidka[2].dostupnost = "Ihned";17obchod.nabidka[3] = {};18obchod.nabidka[3].cena = 500;19obchod.nabidka[3].nazev = "Voda";20obchod.nabidka[3].dostupnost = "5 dní";21print("Adresa obchodu:");22print(obchod.info.ulice.." "..obchod.info.cp);23print(obchod.info.mesto);24print("");25print("Nabidka obchodu:");26for _,v in pairs(obchod.nabidka) do27 print(v.nazev.." - Cena: "..v.cena.." Kc");28 print("Dostupnost: "..v.dostupnost);29 print("");30end;3132--[[ LOG:33 Adresa obchodu:34 Kratochvilova 7/149035 Ostrava - Moravska Ostrava3637 Nabidka obchodu:38 Bonbony - Cena: 5000 Kc39 Dostupnost: Ihned4041 Ubytovani - Cena: 1000 Kc42 Dostupnost: Ihned4344 Voda - Cena: 500 Kc45 Dostupnost: 5 dní46]]--47
VÃcesložkovou tabulku vytvoÅ™Ãme tak, že položce pole pÅ™idÄ›lÃme hodnotu {}
Knihovna table
Tak jako Å™etÄ›zce majà knihovnu string, má Lua knihovnu také pro tabulky. Tato knihovna obsahuje funkce pro práci s tabulkami a my si je dnes popÃÅ¡eme. Tato knihovna je o nÄ›co menÅ¡Ã než ty pÅ™edchozÃ, protože téměř cokoli co chceme udÄ›lat s tabulkou si můžeme udÄ›lat jinak než pÅ™es tuto knihovnu.
table.concat();
Tato funkce sloužà ke spojenà obsahu tabulky v jeden Å™etÄ›zec. Jenà vstupnà parametry jsou tabulka a nepovinný oddÄ›lovaÄ, zaÄátek a konec. Funkce spojà obsah tabulky a pokud je pÅ™Ãtomen oddÄ›lovaÄ, vložà ho mezi jednotlivé položky. VýstupnÃm parametrem je Å™etÄ›zec, který vznikne pÅ™i spojenÃ. Pokud nenà pÅ™Ãtomen konec ale jen zaÄátek, spojà se to co je za zaÄátkem (vÄetnÄ›).
Pozor! Pokud bude tabulka obsahovat funkce nebo dalšà tabulky, funkce selže.
1-- naplneni pole pri inicializaci2local tabulka = {1,68,"f ",65,"fabr"};3print(table.concat(tabulka));4-- "168f 65fabr"5print(table.concat(tabulka," - "));6-- "1 - 68 - f - 65 - fabr"7-- vytvoreni tabulky na radku8print(table.concat({{},5,84,6,2}));9-- "Error: Running LUA method 'update'."10-- "C:/Users/Martin/Documents/My Games/FarmingSimulator2015/mods//JD_pack/Script/MujSkript.lua:16: invalid value (table) at index 1 in table for 'concat'"11
Zde vidÃte dokonce jakou chybu vám hra vygeneruje pokud pro concat zvolÃte Å¡patnou tabulku.
table.getn(); , #
Funkce table.getn(); vracà poÄet záznmů v tabulce. VstupnÃm parametrem je tabulka, výstupnÃm pak ÄÃslo, kolik obsahuje záznamů. Stejnou funkci plnà znak # pÅ™ed názvem tabulky. Pozor: table.getn(); se pÅ™estává použÃvat - doporuÄuji použÃvat #. Ukázka:
1-- naplneni pole pri inicializaci2local tabulka = {1,68,"f ",65,"fabr"};3print(table.getn(tabulka));4-- "5"5print(#tabulka);6-- "5"
table.sort();
Funkce seÅ™adà tabulku podle hodnot. Parametry jsou tabulka a porovnávacà funkce. Výstup nenà žádný - zmÄ›ny se provedou pÅ™Ãmo v tabulce. Porovnávacà funkce musà vracet pravdivostnà hodnotu true nebo false. VstupnÃmi parametry této porovnávacà funkce jsou hodnoty a a b. Vrácená hodnota porovnávacà funkce urÄuje, zda má být parametr a umÃstÄ›n pÅ™ed parametrem b.
Ukázka table.sort();:
1-- naplneni pole pri inicializaci2local tabulka = {1,68,5,65,456};3-- serazeni bez porovnavaci funkce:4table.sort(tabulka);5print(table.concat(tabulka," - "));6-- "1 - 5 - 65 - 68 - 456"78-- pouziti porovnavaci funkce:9table.sort(tabulka,function(a,b)10 -- B bude pred A pokud je mensi11 return (a>b);12end);13print(table.concat(tabulka," - "));14-- "456 - 68 - 65 - 5 - 1"1516tabulka = {"afn", 64, "b", 69,2};17table.sort(tabulka);18print(table.concat(tabulka," - "));19-- "Error: Running LUA method 'update'."20-- "attempt to compare number with string"2122-- Tuto chybu opravime tak, ze pouzijeme vlastni porovnavaci funkci.23table.sort(tabulka, function(a,b)24 if type(a) == "string" and type(b) == "number" then25 return false;26 elseif type(b) == "string" and type(a) == "number" then27 return true;28 elseif type(b) == "string" and type(a) == "string" then29 return a30 end;31end);32-- diky teto funkci si posuneme vsechny texty na konec tabulky33print(table.concat(tabulka," - "));34-- "2 - 64 - 69 - afn - b"35
V pÅ™ikladu je použita funkce type o které si budeme povÃdat pozdÄ›ji. Tato funkce vracà datový typ dané promÄ›nné.
table.insert();
Tato funkce má za úkol vkládat do tabulky data. VstupnÃmi parametry jsou tabulka, nepovinná pozice a povinná hodnota. Funkce nevracà nic - zmÄ›ny se provedou pÅ™Ãmo v tabulce. Pokud nenà urÄena pozice prvku, bude vložen na konec tabulky. PÅ™i urÄenà pozice jsou následujÃcà prvky v tabulce posunuty. Ukázka:
1local tabulka = {"a",77,45,"asdfg"};2print(table.concat(tabulka,", "));3-- "a, 77, 45, asdfg"4table.insert(tabulka,"vlozeny jsem");5print(table.concat(tabulka,", "));6-- "a, 77, 45, asdfg, vlozeny jsem"7table.insert(tabulka,3,"hihi");8print(table.concat(tabulka,", "));9-- "a, 77, hihi, 45, asdfg, vlozeny jsem"
table.remove();
Funkce odstranà jeden záznam z tabulky podle zadaných parametrů. Těmi jsou tabulka a nepovinná pozice prvku. Pokud nenà udána pozice prvku, smaže se poslednà záznam - jinak se maže záznam na dané pozici. Ukázka:
1local tabulka = {"a",77,45,"asdfg"};2table.insert(tabulka,"vlozeny jsem");3table.insert(tabulka,3,"hihi");4table.remove(tabulka);5print(table.concat(tabulka,", "));6-- "a, 77, hihi, 45, asdfg"7table.remove(tabulka, 2);8print(table.concat(tabulka,", "));9-- "a, hihi, 45, asdfg"