Module:User:Erutuon/lang stuff/map

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