Moduuli:Mallinetyokalut
![](http://178.128.105.246/cars-http-upload.wikimedia.org/wikipedia/commons/thumb/1/19/Test_Template_Info-Icon.svg/50px-Test_Template_Info-Icon.svg.png)
Moduulin Mallinetyokalut käyttöohje [näytä tämä käyttöohje omalla sivullaan] [muokkaa tätä käyttöohjetta] [päivitä] [testit] [hiekkalaatikko]
![]() |
Tässä ohjeessa kuvataan toiminnallisuutta jonka kehitys on vielä kesken. Sivu on tarkoitettu lähinnä kehityksen apuvälineeksi, ei yleiseen käyttöön. |
Hyödyllisiä apufunktiota mallineiden parametrien käsittelyyn.
Funktiot
[muokkaa]ensimmainen_ei_tyhja
[muokkaa]ensimmainen_ei_tyhja(luettelo)
Palauttaa ensimmäisessä parametrissa annetusta luettelosta ensimmäisen arvon joka ei ole nil tai tyhjä merkkijono. Funktiota voi käyttää tutkittaessa mitä parametreja on annettu, kun tyhjän parametrin halutaan vastaavan antamatonta arvoa. Jos parametria ei ole annettu ollenkaan, on sen arvo nil. Jos sen kenttä on jätetty tyhjäksi, on sen arvo "".
Parametrit:
- luettelo arvoista
Esim.
ensimmainen_ei_tyhja{"", nil, "arvo1", "arvo2"} -- palauttaa "arvo1"
ensimmainen_ei_tyhja{""} -- palauttaa nil
numeroidut_parametrit
[muokkaa]numeroidut_parametrit(args, nimet)
Palauttaa annettua taulukkoa args vastaavan taulukon, jossa numeroidut parametrit on muutettu taulukon alkioiksi.
Parametrit:
- frame-olion args-kenttä
- Parametrit, joista tehdään luettelo vaikka niitä ei olisi numeroitu. Huom. Funktio tekee luettelon kaikista numerollisista parametreista, mutta koodin ymmärrettävyyden kannalta on tässä parametrissa hyvä luetella kaikki parametrinimet, joita halutaan myöhemmin käyttää.
Esim.
numeroidut_parametrit({ mon1 = "eka", mon2 = "toka" }, { "mon" }) -- palauttaa { mon = { "eka", "toka" } }
2. parametri on hyödyllinen, kun arvo voidaan antaa joko numerolla tai ilman (jolloin numeroton arvo vastaa 1:tä).
numeroidut_parametrit({ mon = "eka", mon2 = "toka" }, { "mon" }) -- palauttaa { mon = { "eka", "toka" } }
Jos tasoja on useampia, ne erotetaan pisteellä:
local args = {
["p1"] = "何",
["plat1.1"] = "eka",
["plat1.2"] = "toka",
["p2"] = "مايو",
["plat2.1"] = "kolkki"
}
numeroidut_parametrit(args, { "p", "plat" })
-- Tulos: { p = { "何", "مايو" }, plat = { { "eka", "toka" }, { "kolkki" } }
local p = {}
--- TODO: POIS ei liity mallineisiin ---->
--- Kutsuu funktiota `func` kaikille taulukon `arr` arvoille ja palauttaa tulokset taulukkona.
--
-- @param func: funktio muotoa f(p)
-- @param arr: taulukko
-- @return: taulukko
function p.map(func, arr)
local out = {}
for i, v in ipairs(arr) do
out[i] = func(v)
end
return out
end
function p.map2(func, arr1, arr2)
local out = {}
local v1, v2
for i = 1, math.max(#arr1, #arr2) do
v1 = arr1[i]
v2 = arr2[i]
out[i] = func(v1, v2)
end
return out
end
--- Palauttaa uuden taulukon, jossa annettujen taulukoiden arvot on paritettu.
--
-- Käyttö: zip(taulukko1, taulukko2, [taulukko3 ...])
--
-- Esim. zip({1, 2, 3}, {"a", "b", "c"})
-- --> { {1, "a"}, {2, "b"}, {3, "c"} }
--
function p.zip(...)
local out = {}
local len = 0
local args = {...}
for i_arr, arr in ipairs(args) do
assert(type(arr) == "table", "Argumentti " .. i_arr .. " ei ole taulukko")
len = math.max(len, #arr)
end
for i_item = 1, len do
out[i_item] = {}
for i_arr, arr in ipairs(args) do
out[i_item][i_arr] = arr[i_item]
end
end
return out
end
function p.filter(func, arr)
local out = {}
for i, v in ipairs(arr) do
if func(v) then
out[i] = v
end
end
return out
end
--- <---- POIS
--- Erottaa ryhmiä annetun taulukon avaimista etuliitteiden perusteella.
--
-- Jos etuliite sisältyy toiseen, menee arvo pisimmän etuliiteen mukaiseen ryhmään.
--
-- @param arr: taulukko, esim. mallineen frame.args-parametrit
-- @param prefiksit: taulukko, jossa avaimet ovat prefiksejä ja arvot ryhmiä, joihin kyseisellä
-- prefiksillä alkavat arvot laitetaan
-- @return: taulukko, jossa on kullekin prefiksille oma kohta. Prefiksittömät menevät 0-alkion alle.
--
-- Esim.
-- m.ryhmittele_prefikseittain({
-- ["nom.m"] = "blörgus",
-- ["nom.f"] = "blörga",
-- ["nom.n"] = "blörgum",
-- ["komp.nom.m"] = "blörgämpus",
-- ["komp.nom.f"] = "blörgämpa",
-- ["komp.nom.n"] = "blörgämpum",
-- ["sup.nom.m"] = "blöginus",
-- ["sup.nom.f"] = "blörgina",
-- ["sup.nom.n"] = "blörginum",
-- }, {
-- ["komp."] = "komp",
-- ["sup."] = "sup",
-- })
-- --> {
-- [0] = {
-- ["nom.m"] = "blörgus",
-- ["nom.f"] = "blörga",
-- ["nom.n"] = "blörgum"
-- },
-- ["komp"] = {
-- ["nom.m"] = "blörgämpus",
-- ["nom.f"] = "blörgämpa",
-- ["nom.n"] = "blörgämpum"
-- },
-- ["komp.testi"] = {
-- ["nom.m"] = "blöginus",
-- ["nom.f"] = "blörgina",
-- ["nom.n"] = "blörginum"
-- }
-- }
--
function p.ryhmittele_prefikseittain(arr, prefiksit)
local out = { [0] = {} }
local prefiksit_list = {}
for prefiksi, ryhma in pairs(prefiksit) do
assert ( type(prefiksi) == "string", "virheellinen prefiksi" )
assert ( type(ryhma) == "string", "virheellinen ryhmä (prefiksi: " .. prefiksi .. ")" )
table.insert(prefiksit_list, prefiksi)
out[ryhma] = {}
end
-- Lajitellaan pisimmästä lyhimpään siltä varalta, että jokin prefiksi on
-- toisen prefiksin alku.
table.sort(prefiksit_list, function (a, b) return #b < #a end)
for key, val in pairs(arr) do
local lisatty = false
for i, prefiksi in ipairs(prefiksit_list) do
local ryhma = prefiksit[prefiksi]
local alku = mw.ustring.sub(key, 1, #prefiksi)
local loppu = mw.ustring.sub(key, #prefiksi + 1)
if alku == prefiksi then
out[ryhma][loppu] = val
lisatty = true
break
end
end
if not lisatty then
out[0][key] = val
end
end
return out
end
--- Palauttaa ensimmäisen ei-tyhjän arvon annetusta luettelosta.
--
-- Tyhjäksi arvoksi lasketaan nil ja tyhjä merkkijono.
-- Esim.
-- p.ensimmainen_ei_tyhja{"", nil, "arvo1", "arvo2"}
-- palauttaa "arvo1".
--
function p.ensimmainen_ei_tyhja(params)
for i = 1, #params do
local val = params[i]
if val ~= nil and val ~= "" then
return val
end
end
return nil
end
--- Palauttaa uuden taulukon, jossa on annetusta taulukosta kaikki muut arvot paitsi pelkkiä tyhjiä merkkejä sisältävät.
-- Funktiolla voi poistaa malllineen parametreista anatamattomat arvot silloin kun tyhjä kenttä vastaa antamatonta arvoa.
--
-- @param params: (yksiulotteinen) taulukko
-- @return: sama taulukko ilman tyhjiä kenttiä
--
-- Esim. poista_tyhjat({
-- ["y.nom"] = "uugi",
-- ["y.gen"] = "",
-- ["y.part"] = "buugi"
-- })
-- palauttaa:
-- {
-- ["y.nom"] = "uugi",
-- ["y.part"] = "buugi"
-- }
function p.poista_tyhjat(params)
local out = {}
for k,v in pairs(params) do
if not mw.ustring.match(v, "^%s*$") then
if tonumber(k) == k then
table.insert(out, v)
else
out[k] = v
end
end
end
return out
end
--- Erottaa pisteillä erotetut numerot nimen lopusta.
--
-- Apufunktio numeroidut_parametrit -funktiolle.
--
-- Esim. "mon1" -> "mon", 1;
-- "param2.3" -> "param", 2, 3;
-- "y3muoto1" -> "y3muoto", 1.
local function erota_osat(sana)
-- Etsitään lopusta alkaen, jotta nimi voi sisältää numeroita.
if type(sana) ~= "string" then
return { sana }
end
local rev = sana:reverse()
local nums = string.match(rev, "^([%d.]*)"):reverse()
if nums == "" then
return { sana }
end
local name = string.sub(sana, 1, sana:len() - nums:len())
local ns = {}
for num in string.gmatch(nums, "([%d]+)") do
table.insert(ns, tonumber(num))
end
return { name, unpack(ns) }
end
local function key_compare(a, b)
local a = string.match(a or "", "([0-9]*)$")
local b = string.match(b or "", "([0-9]*)$")
return (tonumber(a) or 0) < (tonumber(b) or 0)
end
--- Palauttaa taulukon avaimet numerojärjestyksessä.
--
-- Huom. varmistaa vain, että numeroidut nimet ovat järjestyksessä
-- (esim. "xx1" tulee ennen "xx2"). Ei muuten nimet ovat
-- edelleen satunnaisessa järjestyksessä.
local function ordered_keys(tbl)
local keyset = {}
local n = 0
for k,v in pairs(tbl) do
n = n + 1
keyset[n] = k
end
table.sort(keyset, key_compare)
return keyset
end
--- Muuttaa assosiatiivisen taulukon, jossa avaimet on numeroitu, sisäkkäisiksi taulukoiksi.
--
-- Syötetaulukon numerot erotetaan pisteillä (paitsi ensimmäinen). Numeroimattomat ("a") ja
-- ylemmän tason ylimääräiset arvot ("c1") jätetään pois ilman virheilmoitusta.
-- Esim. { ["a"] = "X",
-- ["a2"] = "A",
-- ["b1"] = "B",
-- ["b2"] = "C",
-- ["c1"] = "X",
-- ["c1.1"] = "D" }
--
-- -> { ["a"] = { [2] = "A" },
-- ["b"] = { "B",
-- "C" },
-- ["c"] = { { "D" } } }
-- @param args: taulukko, jossa on numeroon päättyviä avaimia
-- @param nimet: taulukkoon ainakin tulevat avaimet. Numeroton arvo tulkitaan 1:seksi.
-- Esim. "mon" = "mon1" -> { "mon" = { [1] = ... } }
function p.numeroidut_parametrit(args, nimet)
local out = {}
local cur_node
local path_
local cur_p
if nimet then
for i, v in ipairs(nimet) do
if args[v] then
out[v] = {}
out[v][1] = args[v]
end
end
end
local keys = ordered_keys(args)
for _, key in ipairs(keys) do
local val = args[key]
path_ = erota_osat(key)
cur_node = out
if #path_ > 1 then
-- Etsitään/luodaan polun päätepiste.
for i = 1, (#path_ - 1) do
cur_p = path_[i]
-- Jos type on "string", on annettu kaksi eritasoista samannimistä arvoa. Ohitetaan
-- äänettömästi, koska monissa mallineissa on esim. "mon" ja "mon2".
if type(cur_node[cur_p]) ~= "table" then
cur_node[cur_p] = {}
end
cur_node = cur_node[cur_p]
end
table.insert(cur_node, val)
end
end
return out
end
--- Yhdistää kaksi taulukkoa uudeksi taulukoksi.
--
-- Jos molemmissa on sama avain, tulee uuteen taulukkoon jälkimmäinen.
function p.yhdista(eka, toka)
local out = {}
for k,v in pairs(eka) do
out[k] = v
end
for k,v in pairs(toka) do
out[k] = v
end
return out
end
--- Luo uuden taulukon taulukon `arr` pohjalta siten, että kukin arvo esiintyy vain kerran.
--
-- Elementtien järjestys noudattaa elementtien ensimmäisiä esiintymiä.
--
-- @param arr: taulukko
-- @param hash_f: jos taulukon `arr` elementit ovat taulukoita, annetaan tällä parametrilla
-- hajautusarvon laskeva funktio. Funktion tulee olla sellainen, että se ottaa
-- alkion parametriksi ja paluttaa joko merkkijonon tai numeron siten, että
-- kaksi samanlaista alkiota palauttavat saman arvon eikä kaksi erilaista
-- alkiota palauta samaa arvoa.
-- @return: taulukon arr elementit tuplat poistettuna
--
-- Esim. 1. Alkeistyypeillä
-- poista_tuplat({ "a", "b", "c", "a", "a", "d", "b" })
-- --> { "a", "b", "c", "d" }
--
-- Esim. 2. Taulukkotyypeillä
-- m.poista_tuplat({
-- { "burger", "m" },
-- { "berger", "f" },
-- { "burger", "m" },
-- { "berger", "m" },
-- { "berger", "f" },
-- }, function (item) return item[1] .. " " .. item[2] end)
-- )
-- --> {
-- { "burger", "m" },
-- { "berger", "f" },
-- { "berger", "m" }
-- }
--
function p.poista_tuplat(arr, hash_f)
local out = {}
local seen = {}
local key
for i, val in ipairs(arr) do
if hash_f then
key = hash_f(val)
else
assert ( type(val) ~= "table", "Tarvitaan hajautusfunktio" )
key = val
end
if not seen[key] then
out[#out + 1] = val
end
seen[key] = true
end
return out
end
function p.sisaltyy(taulukko, arvo)
for i, val in ipairs(taulukko) do
if val == arvo then
return true
end
end
return false
end
return p