Moduuli:Mallinetyokalut/hiekkalaatikko
Tämän moduulin ohjeistuksen voi tehdä sivulle Moduuli:Mallinetyokalut/hiekkalaatikko/ohje
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