Module:XM

-- -- Class methods local class = {}

function class.search(k, list) for i = 1, table.getn(list) do       local v = list[i][k] if v then return v end end end

function class.create(...) local c = {} setmetatable(c, {       __index = function(t, k)            return class.search(k, arg)        end    })

c.__index = c   function c:new(o) o = o or {} setmetatable(o, c)       return o    end return c end

-- Array methods local array = {}

function array.map(a, func) local arr = {} for k, v in ipairs(a) do       arr[k] = func(v, k, a)    end return arr end

function array.some(a, func) local valid = false for k, v in ipairs(a) do       local b = func(v, k, a)        if b == true then valid = true break end end return valid end

function array.every(a, func) local valid = true for k, v in ipairs(a) do       local b = func(v, k, a)        if b == false then valid = false break end end return valid end

function array.filter(a, func) local arr = {} for k, v in ipairs(a) do       local c = func(v, k, a)        if c == true then arr[k] = v       end end return arr end

function array.exclude(a, func) local arr = {} for k, v in ipairs(a) do       local c = func(v, k, a)        if c == false then arr[k] = v       end end return arr end

function array.forEach(a, func) for k, v in ipairs(a) do       func(v, k, a)    end end

function array.fill(a, value) local arr = {} for k, v in ipairs(a) do       arr[k] = value end return arr end

function array.reduce(a, func, initialValue) local value = initialValue or {} for k, v in ipairs(a) do       if pcall(function return a[k] end) then value = func(value, v, k, a)       end end return value end

function array.length(a) local length = 0 for _ in ipairs(a) do length = length + 1 end return length end

function array.join(a, sep) return table.concat(a, sep or "") end

-- Object methods

local object = {}

function object.has(obj, prop) return pcall(function return obj[prop] ~= nil end) end

function object.length(obj) local length = 0 for _ in pairs(a) do length = length + 1 end return length end

function object.keys(obj) local keys = {} local index = 1 for k, _ in pairs(obj) do       keys[index] = k        index = index + 1 end return keys end

function object.values(obj) local values = {} local index = 1 for _, v in pairs(obj) do       values[index] = v        index = index + 1 end return values end

function object.typeof(val) local _type = type(val) if (_type ~= "table" and _type ~= "userdata") then return _type end local _meta = getmetatable(val) if (_meta ~= nil and _meta._NAME ~= nil) then return _meta._name else return _type end end

function object.entries(obj) local arr = {} local i = 1 for k, v in pairs(obj) do       local values = {} values[1] = k       values[2] = v        arr[i] = values i = i + 1 end return arr end

-- String methods

local str = {}

function str.split(s, sep) local parts = {} local index = 1 local magic = ".%+-*?[]^$" if (sep == nil) then sep = "%s" elseif (string.find(sep, magic, 1, true)) then sep = "%" .. sep end local pattern = "[^" .. sep .. "]+"   for w in string.gmatch(s, pattern) do        parts[index] = w        index = index + 1 end return parts end

function str.replace(s, repl, res) local magic = ".%+-*?[]^$" local matches = {} if (repl == nil) then repl = "%s" elseif (string.find(repl, magic, 1, true)) then repl = "%" .. repl end local pattern = "[^" .. repl .. "]"   if (res == nil) then return string.gsub(s, repl, "") elseif (object.typeof(res) == "function" or object.typeof(res) == "string") then return string.gsub(s, repl, res) end return "" end

function str.lower(s) return string.lower(s) end

function str.upper(s) return string.upper(s) end

return { array = array, object = object, str = str }