Module:TableUtil

From Leaguepedia | League of Legends Esports Wiki
Jump to: navigation, search

To edit the documentation or categories for this module, click here.


local lang = mw.getLanguage('en')

local p = {}

function p.generalLength(tbl)
	local n = 0
	for _, _ in pairs(tbl) do
		n = n + 1
	end
	return n
end

function p.getKeysAndSort(tbl, f)
	local ret = {}
	for k, _ in pairs(tbl) do
		ret[#ret+1] = k
	end
	table.sort(ret, f)
	return ret
end

function p.keyOf(tbl, val)
	for k, v in pairs(tbl) do
		if v == val then
			return k
		end
	end
	return nil
end

function p.hash(tbl)
	local hash = {}
	for k, v in pairs(tbl) do
		hash[v] = k
	end
	return hash
end

function p.appendHash(parent, tbl)
	for k, v in pairs(tbl) do
		parent[v] = k
	end
	return parent
end

-- sorts tblToSort to be in the same order as the elements appear in lookup
function p.sortByKeyOrder(tblToSort,values)
	local lookup = p.hash(values)
	table.sort(tblToSort, function (a,b)
			return (lookup[a] or 0) < (lookup[b] or 0)
		end
	)
	return
end

function p.sortUnique(tbl)
	table.sort(tbl)
	local tbl2 = {}
	local i = 0
	for k, v in ipairs(tbl) do
		if v ~= tbl2[i] then
			i = i + 1
			tbl2[i] = v
		end
	end
	return tbl2
end

function p.mergeArrays(tbl1,tbl2)
	-- tbl1 is modified to include the elements of tbl2 appended to the end. Order is preserved.
	if not tbl1 then tbl1 = {} end
	if not tbl2 then tbl2 = {} end
	for _, v in ipairs(tbl2) do
		tbl1[#tbl1+1] = v
	end
	return tbl1
end

function p.merge(tbl1, ...)
	-- tbl1 is modified to include all the elements of tbl2.
	if not tbl1 then tbl1 = {} end
	local tables = {...}
	for _, tbl2 in ipairs(tables) do
		for k, v in pairs(tbl2) do
			tbl1[k] = v
		end
	end
	return tbl1
end

-- table.remove for non-integer key
function p.remove(tbl, key)
	local output = tbl[key]
	tbl[key] = nil
	return output
end

function p.removeDuplicates(tbl)
	local hash = {}
	local ret = {}
	for _, v in ipairs(tbl) do
		if not hash[v] then
			hash[v] = true
			ret[#ret+1] = v
		end
	end
	return ret
end

-- returns a copy of tbl with the elements in opposite order (not a deep copy)
function p.reverse(tbl)
	local tbl2 = {}
	local len = #tbl
	for i = len, 1, -1 do
		tbl2[len - i + 1] = tbl[i]
	end
	return tbl2
end

function p.reverseInPlace(tbl)
	local len = #tbl
	local stop_at = len / 2
	for i = 1, stop_at do
		local temp = tbl[i]
		tbl[i] = tbl[len - i + 1]
		tbl[len - i + 1] = temp
	end
end

function p.shallowClone(tbl)
	-- mostly to be able to use # operator on something from mw.loadData
	local tbl2 = {}
	for k, v in pairs(tbl) do
		tbl2[k] = v
	end
	return tbl2
end

function p.slice(tbl, s, e)
	local tbl2 = {}
	for k = s, e do
		tbl2[#tbl2+1] = tbl[k]
	end
	return tbl2
end

-- prints the table as a comma-separated list with and
function p.printList(tbl)
	if #tbl == 1 then
		return tbl[1]
	elseif #tbl == 2 then
		return table.concat(tbl, ' and ')
	else
		last = table.remove(tbl, #tbl)
		list = table.concat(tbl, ', ')
		return list .. ', and ' .. (last or '')
	end
end

function p.removeFalseEntries(tbl, max)
	if not max then max = #tbl end
	local j = 0
	for i = 1, max do
		if tbl[i] then
			j = j + 1
			tbl[j] = tbl[i]
		end
	end
	for i = j+1, max do
		tbl[i] = nil
	end
	return tbl
end

function p.padFalseEntries(tbl, max, default)
	default = default or ''
	for i = 1, max do
		if not tbl[i] then
			tbl[i] = default
		end
	end
	return tbl
end

function p.mapInPlace(tbl, f)
	for k, v in pairs(tbl) do
		tbl[k] = f(v)
	end
	return tbl
end

function p.mapArrayInPlace(tbl, f)
	for k, v in ipairs(tbl) do
		tbl[k] = f(v)
	end
	return tbl
end

function p.mapSafe(tbl, f)
	local tbl2 = mw.clone(tbl)
	p.removeFalseEntries(tbl2)
	for k, v in ipairs(tbl2) do
		tbl2[k] = f(v)
	end
	return tbl2
end

function p.mapDictInPlace(tbl, f, ...)
	for _, v in ipairs(tbl) do
		tbl[v] = f(tbl[v], ...)
	end
	return tbl
end

function p.mapRowsInPlace(tbl, f)
	for k, row in ipairs(tbl) do
		f(row)
	end
	return tbl
end

function p.mapDictRowsInPlace(tbl, f)
	for _, v in ipairs(tbl) do
		f(tbl[v])
	end
	return tbl
end

function p.concat(tbl, sep, f, max)	
	-- f is a function that doesn't take any additional args
	if not sep then sep = ',' end
	if f then
		p.mapArrayInPlace(tbl, f)
	else
		p.removeFalseEntries(tbl, max)
	end
	return table.concat(tbl, sep)
end

function p.concatSafe(tbl, sep, f)	
	-- f is a function that doesn't take any additional args
	local tbl2 = mw.clone(tbl)
	if f then
		p.mapInPlace(tbl2, f)
	else
		p.removeFalseEntries(tbl2)
	end
	return table.concat(tbl2, sep)
end

function p.concatFromArgs(args, argname, sep, f)
	-- if fields are saved in args as field1, field2, field3, etc
	local i = 1
	local tbl = {}
	if args[argname] then
		tbl[1] = args[argname]
		i = 2
	end
	while args[argname .. i] do
		tbl[i] = args[argname .. i]
		i = i + 1
	end
	return next(tbl) and p.concat(tbl, sep, f)
end

function p.crop(tbl, max)
	for k, _ in ipairs(tbl) do
		if k > max then
			tbl[k] = nil
		end
	end
end

function p.alphabetize(tbl)
	local hash = {}
	local nocase = {}
	for i, v in ipairs(tbl) do
		nocase[i] = lang:caseFold(v)
		hash[nocase[i]] = v
	end
	table.sort(nocase)
	for i, v in ipairs(nocase) do
		tbl[i] = hash[v]
	end
	return tbl
end

function p.guaranteeTable(c)
	if not c then return nil end
	if type(c) == 'table' then
		return c
	end
	return { c }
end

function p.concatIfTable(tbl, sep)
	if not tbl then return nil end
	return p.concat(p.guaranteeTable(tbl), sep)
end

return p