local Map_methods = {}
-- metatable for Maps
local Map = { __index = Map_methods }
-- Cache Module:array here.
local array_constructor
-- Names of functions in [[Module:table]].
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[k] 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[k] = 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[k] = 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 [[Module:table]].
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[key] 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[key]
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[key] = 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