Halo Esports Wiki

We are currently performing extensive maintenance to this wiki and as a result there will likely be errors. Please be patient while we work to fix all problems.

READ MORE

Halo Esports Wiki
Advertisement

Documentation for this module may be created at Module:OrderedDict/doc

local LCS = require('Module:LuaClassSystem')
local util_vars = require("Module:VarsUtil")
local util_sort = require("Module:SortUtil")

local OD = {}
local p = LCS.class()

-----------------------------------
-- ordered dict metatable
-----------------------------------
function OD.__ipairs(tbl)
	local function stateless_iter(tbl, i)
		-- Implement your own index, value selection logic
		i = i + 1
		local key = tbl[i]
		local val = tbl[key]
		if key ~= nil and val ~= nil then return i, key, val end
	end

	-- return iterator function, table, and starting point
	return stateless_iter, tbl, 0
end

-- function OD.__pairs(tbl)
-- 	error('Attempting to call pairs on an ordered dictionary')
-- end

function OD.__newindex(tbl, key, value)
	rawset(tbl, #tbl+1, key)
	rawset(tbl, key, value)
end

function OD.__index(tbl, key)
	if type(key) ~= 'number' then
		return rawget(tbl, key)
	end
	return rawget(tbl, key) -- , rawget(tbl, tbl[key])
end


-----------------------------------
-- class methods
-----------------------------------
function p:init()
	rawset(self, "_dict", {})
	rawset(self, "_hash", {})
	local function __newindex(tbl, key, value)
		tbl._dict[key] = value
	end
	getmetatable(self).__newindex = __newindex
	local function __ipairs(tbl)
		return ipairs(tbl._dict)
	end
	getmetatable(self).__ipairs = __ipairs
	setmetatable(self._dict, OD)
end

function p:concat(sep, f, ...)
	local tbl = {}
	for _, _, v in ipairs(self) do
		tbl[#tbl+1] = f and f(v, ...) or v
	end
	return table.concat(tbl, sep or ',')
end

function p:concatKeys(sep, f, ...)
	local tbl = {}
	for _, k, _ in ipairs(self) do
		tbl[#tbl+1] = f and f(k, ...) or k
	end
	return table.concat(tbl, sep or ',')
end

function p:formatAndConcat(sep, str)
	return self:concat(sep, function(val)
		return str:format(val)
	end)
end

function p:formatAndConcatKeys(sep, str)
	return self:concatKeys(sep, function(key)
		return str:format(key)
	end)
end

function p:get(key)
	return self._dict[key]
end

function p:set(key, val)
	self._dict[key] = val
	self._hash[key] = self._hash[key] or #self._dict
end

function p:mapRows(f, ...)
	for _, _, v in ipairs(self) do
		f(v, ...)
	end
end

function p:mapInPlace(f, ...)
	for i, k, v in ipairs(self) do
		self:set(k, f(i, k, v, ...))
	end
end

function p:removeKey(key)
	if not self._hash[key] then return end
	self._dict[key] = nil
	table.remove(self._dict, self._hash[key])
	for i = self._hash[key], #self._dict do
		self._hash[self:get(i)] = i
	end
	self._hash[key] = nil
end

function p:removeIndex(index)
	if not self._dict[key] then return end
	for i = index, #self._dict do
		self._hash[self:get(i)] = i
	end
	self._hash[index] = nil
	self._dict[self:get(index)] = nil
	table.remove(self._dict, index)
end

function p:toList()
	local ret = {}
	for i, _, v in ipairs(self._dict) do
		ret[i] = v
	end
	return ret
end

function p:toDict()
	local ret = {}
	for i, k, v in ipairs(self._dict) do
		ret[i] = k
		ret[k] = v
	end
	return ret
end

function p:sortByKeys(keys, increasing)
	util_sort.dictByKeys(self._dict, keys, increasing)
	for i, k, _ in ipairs(self._dict) do
		self._hash[k] = i
	end
end

return p
Advertisement