Moduuli:Mallinetyokalut

Wikisanakirjasta
Siirry navigaatioon Siirry hakuun
Template-info.png
Under construction icon-yellow.svg 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:

  1. 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:

  1. frame-olion args-kenttä
  2. 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 = {}

--- 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 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
	    out[k] = v
	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

--- 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

   for key, val in pairs(args) do
      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
         
         cur_p = path_[#path_]
         
         -- Jos ei ole nil, sama kuin yllä. (Avaimet tulee satunnaisessa järjestyksessä.)
         if cur_node[cur_p] == nil then
            cur_node[cur_p] = val
         end
      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

return p