Neater way to work with data modules with string keys, similar to Module:array.
-- Get data tables for languages with transliteration modules.
local Map = require("Module:User:Erutuon/lang stuff/map")
local has_transliteration_module = Map:new(require 'Module:languages/data/2')
:filter(function (data) return data.translit_module ~= nil end)
-- Create list of their canonical names and codes.
has_transliteration_module
:map(function (data, code) return ("%s (%s)"):format(data, code) end)
:values() -- Returns array from Module:array.
:sort()
:concat(", ")
--> "Abkhaz (ab), Amharic (am), Arabic (ar), Armenian (hy), Assamese (as), Avar (av), Avestan (ae), Bashkir (ba), Belarusian (be), Bengali (bn), Bulgarian (bg), Burmese (my), Chechen (ce), Chuvash (cv), Cree (cr), Dhivehi (dv), Dzongkha (dz), Georgian (ka), Greek (el), Gujarati (gu), Hindi (hi), Inuktitut (iu), Javanese (jv), Kannada (kn), Kashmiri (ks), Kazakh (kk), Khmer (km), Korean (ko), Kurdish (ku), Kyrgyz (ky), Lao (lo), Macedonian (mk), Malayalam (ml), Marathi (mr), Mongolian (mn), Nepali (ne), Old Church Slavonic (cu), Odia (or), Ossetian (os), Punjabi (pa), Russian (ru), Sanskrit (sa), Sichuan Yi (ii), Sinhalese (si), Sundanese (su), Tajik (tg), Tamil (ta), Tatar (tt), Telugu (te), Thai (th), Tibetan (bo), Tigrinya (ti), Ukrainian (uk), Uyghur (ug), Yiddish (yi)"
local Map_methods = {}
-- metatable for Maps
local Map = { __index = Map_methods }
-- Cache Module:array here.
local array_constructor
-- Names of functions in ].
local table_methods = {
"shallowcopy", "deepcopy", "keysToList", "size", "sortedPairs"
}
local create_array = { "keysToList" }
local create_map = { "shallowcopy" }
local aliases = { keys = "keysToList" }
-- Behaves like "next", but filters out methods from "Map_methods".
function Map_methods:next(v)
for k, v in next, self, v do
if not Map_methods then
return k, v
end
end
end
function Map_methods:pairs()
return Map_methods.next, self, nil
end
function Map_methods:map(func)
local new_t = {}
for k, v in self:pairs() do
new_t = func(v, k, self)
end
return Map:new(new_t)
end
function Map_methods:filter(func)
local new_t = {}
for k, v in self:pairs() do
if func(v, k, self) then
new_t = v
end
end
return Map:new(new_t)
end
function Map_methods:values(key)
array_constructor = array_constructor or require "Module:array"
local arr = array_constructor()
for k, v in self:pairs() do
arr:insert(v)
end
return arr
end
-- Create array of values sorted by key and concatenate it with a separator.
function Map_methods:sortedConcat(sep, comp)
array_constructor = array_constructor or require "Module:array"
local arr = array_constructor()
for k, v in self:sortedPairs(comp) do
arr:insert(v)
end
return arr:concat(sep)
end
function Map_methods:log()
mw.logObject(self)
return self
end
local function wrap_in_array_constructor(func)
array_constructor = array_constructor or require "Module:array"
return function (...)
return array_constructor(func(...))
end
end
local function wrap_in_map_constructor(func)
return function (...)
return Map:new(func(...))
end
end
local m_table
-- Grab additional functions from ].
local Map_methods_mt = {}
setmetatable(Map_methods, Map_methods_mt)
function Map_methods_mt:__index(key)
if type(key) ~= "string" then
return nil
end
-- Convert underscores to camel case: num_keys -> numKeys.
key = key:gsub("_(.)", string.upper)
key = aliases or key
local val = rawget(Map_methods, key)
if val then
return val
end
m_table = m_table or require "Module:table"
if key == "toArray" then
val = require "Module:array".from
elseif m_table.contains(table_methods, key) then
val = m_table
if m_table.contains(create_array, key) then
val = wrap_in_array_constructor(val)
elseif m_table.contains(create_map, key) then
val = wrap_in_map_constructor(val)
end
end
if val then
Map_methods = val
return val
end
end
function Map:new(...)
local map
if type((...)) == "table" then
map = ...
local mt = getmetatable(map)
if mt and mt.mw_loadData then
m_table = m_table or require "Module:table"
map = m_table.shallowcopy(map)
end
else
map = {}
end
return setmetatable(map, self)
end
return Map