Modul:TableUtil

Aus Satisfactory Wiki
Zur Navigation springen Zur Suche springen

Die Dokumentation für dieses Modul kann unter Modul:TableUtil/Doku erstellt werden

local checkType = require("libraryUtil").checkType;
local util_text = require('Module:TextUtil')

local floor = math.floor
local infinity = math.huge

local p = {}

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.lookup(tbl)
	local lookup = {}
	for k, v in pairs(tbl) do
		lookup[v] = k
	end
	return lookup
end

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

-- sorts tblToSort to be in the same order as the elements appear in lookup
function p.sortByKeyOrder(tblToSort,values)
	local lookup = p.lookup(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, tbl2)
	-- tbl1 is modified to include all the elements of tbl2.
	if not tbl1 then tbl1 = {} end
	if not tbl2 then tbl2 = {} end
	for k, v in pairs(tbl2) do
		tbl1[k] = v
	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

-- 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, max)
	for k, v in pairs(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.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.splitAndMap(str, f, sep)
	sep = '%s*' .. (sep or ',') .. '%s*'
	return p.mapInPlace(util_text.split(str, sep), f)
end

function p.concat(tbl, sep, f, max)	
	-- f is a function that doesn't take any additional args
	if f then
		p.mapInPlace(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

--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
	if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
		return true
	else
		return false
	end
end

--[[
--------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any
-- numerical keys that have non-nil values, sorted in numerical order.
--------------------------------------------------------------------------------
--]]
function p.numKeys(t)
	checkType('numKeys', 1, t, 'table')
	local isPositiveInteger = p.isPositiveInteger
	local nums = {}
	for k, v in pairs(t) do
		if isPositiveInteger(k) then
			nums[#nums + 1] = k
		end
	end
	table.sort(nums)
	return nums
end

--[[
--------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
--------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
	checkType('compressSparseArray', 1, t, 'table')
	local ret = {}
	local nums = p.numKeys(t)
	for _, num in ipairs(nums) do
		ret[#ret + 1] = t[num]
	end
	return ret
end

--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
	checkType('sparseIpairs', 1, t, 'table')
	local nums = p.numKeys(t)
	local i = 0
	local lim = #nums
	return function ()
		i = i + 1
		if i <= lim then
			local key = nums[i]
			return key, t[key]
		else
			return nil, nil
		end
	end
end

return p