WARFRAME Wiki
WARFRAME Wiki
WARFRAME Wiki
Official wiki
9,066
pages


Table is an extension of the table STL, containing additional functionality and support.

Table can only be used within other modules. It is not recommended to invoke these functions within articles or templates.

All table STL objects can be accessed directly, e.g. table.concat().

Usage

Module

local p = {}
local table = require('Module:Table')

local function func(t)
    return table.size(t)
end

On this Wiki, Table is used in:


Documentation

Package items

table.invertIndex(t, keyName) (function)
Inverts a table to be indexed by a specified first-depth key.
{ t1 = { Value = "Some value", NestedTable = { NestedValue = "Another value" } } } becomes the following if using Value as inverted key { ["Some value"] = { Value = "Some value", NestedTable = { NestedValue = "Another value" } }
Parameters:
  • t Input table with table values or keys that map to table values (unmodified) (string)
  • keyName Name of key to use as inverted index (string)
Returns: Resultant table (table)
table.loadData(t) (function)
Loads a copy of a data table. Being a copy, it is no longer readonly.
Parameter: t Location of data table ([[Module:<Module>/data]] usually) (string)
Returns: Copy of data table (table)
table.sort(t, f) (function)
Sorts an array.
Parameters:
  • t Array-like table to be sorted (table)
  • f Comparator function that takes in two arguments and returns a boolean; if omitted, uses default less-than operation when comparing two values (function; optional)
Returns: Sorted table for function chaining or tail call (table)
table.copyKeyValues(targetTable, refTable, keyTable) (function)
Copying key-value pairs to target table from reference table. Assumes that tables only contain table entries. Keys that are already in target table will not be overrided with data from reference table.
Parameters:
  • targetTable Table to be modified (table)
  • refTable Reference table (table)
  • keyTable Table of key names to copy within each table entry (table)
Returns: Modified target table (table)
table.skpairs(t, sortType) (function)
Iterator sorted by keys.
For example, a table that looked something like
data = {["Cat"] = 5, ["Bat"] = 4, ["Hat"] = 7 }
then
for k, v in skpairs(data) do
would loop through:
k="Bat" v=4;
k="Cat" v=5;
k="Hat" v=7
redone by user:gigamicro
Parameters:
  • t A table to be sorted (table)
  • sortType If true, sort by descending order; ascending otherwise; can also pass a function (boolean or function; optional)
Returns:
  • For loop initialising values (function)
  • Two element table with table values, the first maps keys to their array index and the second is an array of key names (table)
  • Starting key (string)
table.size(table) (function)
Returns the number of elements/entries in a table. If you want to only get the number of number indexed elements use the '#' operator or table.indexCount().
Parameter: table A table with no explicit nil values (table)
Returns: The size of table, ignoring keys with nil values and nil values themselves (number)
table.indexCount(t) (function)
Returns the number of number indexed elements in a table as well as the highest number index.
Parameter: t A table with no explicit nil values (table)
Returns:
  • The number of indexed elements in a table; if table is not of type 'table' then return nil (number)
  • Largest index (not necessarily the same as count since tables can be non-contiguous arrays) (number)
table.tableSort(t, sortCol, sortAscend) (function)
Sorts a table based on the listed column.
Parameters:
  • t Table to be sorted (table)
  • sortCol Name of column to be sorted by (string)
  • sortAscend If true, sorts in ascending order by specified column; false otherwise (boolean)
Returns: Sorted table (table)
table.contains(t, item, ignoreCase) (function)
Checks if a string value is in a table, acting as an array.
Parameters:
  • t A table to be searched through (table)
  • item The element that is being searched for (string)
  • ignoreCase If false, search is case-sensitive; true otherwise (boolean)
Returns:
  • True if element exists in table, false otherwise (boolean)
  • The found element's index; nil if element is not found (number)
  • Value that is found, same as item; nil if element is not found (string)
table.filter(t, search) (function)
Filters tables into subsets.
auth: User:gigamicro
Parameters:
  • t table in which to search (table)
  • search String to search in table's keys (string or function)
Returns: A subset of the original table where search(k, v, t) is true (table)
table.pack(...) (function)
Stores multiple return values into a table, similar to table. pack in Lua 5.2
Parameter: ... Any number of returned values regardless of type (...)
Returns: An array-like table containing the passed in arguments in the order that they are returned (table)

Created with Docbunto

See Also

Code


---	'''Table''' is an extension of the <code>table</code> STL, containing additional functionality 
--	and support.<br/ >
--	
--	Table can only be used within other modules. It is not recommended to invoke
--	these functions within articles or templates.
--	
--	All table STL objects can be accessed directly, e.g. <code>table.concat()</code>.
--	
--	@module		table
--	@alias		p
--	@author		Various
--	@author		[[User:Gigamicro|Gigamicro]]
--	@attribution	[[User:Cephalon Scientia|User:Cephalon Scientia]]
--	@attribution	[[User:FINNER|FINNER]]
--	@image		ModuleTable.png
--	@release	beta
--	<nowiki>

-- TODO: May implement some useful functions from https://developer.roblox.com/en-us/api-reference/lua-docs/table

-- TODO: Add reverse mapping function for simple key-value pairs, returning a 
-- new table with key-value pairs reversed? This is to allow two-way lookup, 
-- assuming values are unique.

local function clone(t1)
	local t2 = {}
	for k, v in ipairs(t1) do
		if type(v) == "table" then t2[k] = clone(v)
		else t2[k] = v end
	end
	-- TODO: Why is there two loops for cloning?
	for k, v in pairs(t1) do
		if type(v) == "table" then t2[k] = clone(v)
		else t2[k] = v end
	end
	return t2
end

local table = {
	--  All Table STL functions  ----------------------------------------------------
	-- https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Table_library
	__concat = table.concat,	-- concatenate indexed values
	__insert = table.insert,	-- add element, increment higher keys
	__remove = table.remove,	-- delete item, move higher keys
	__maxn = table.maxn,	-- deprec?, largest number key
	__sort = table.sort,	-- modified merge sort
	-- Depreciated functions:
	-- table.foreach()	- use for loop with pairs() instead
	-- table.foreachi()	- use for loop with ipairs() instead
	-- table.getn()	- use length operator (#) instead or Table.size() for tables loaded through mw.loadData()
	concat = table.concat,
	insert = table.insert,
	remove = table.remove,
	-- sort = table.sort,	-- Overridden to support function chaining/tail calls
	unpack = unpack,
	
	deepCopy = function(t1)
		local mt = getmetatable(t1)
		if mt and mt.mw_loadData then
			return clone(t1)
		end
		return mw.clone(t1)
	end,
	shallowCopy = function(t) return clone(t) end
}

---	Inverts a table to be indexed by a specified first-depth key.
--	<pre>
--	{
--		t1 = {
--			Value = "Some value",
--			NestedTable = {
--				NestedValue = "Another value"
--			}
--		}
--	}
--	becomes the following if using Value as inverted key
--	{
--	["Some value"] = {
--		Value = "Some value",
--		NestedTable = {
--			NestedValue = "Another value"
--		}
--	}
--	</pre>
--	@function		p.invertIndex
--	@param			{string} t Input table with table values or keys that map to table values (unmodified)
--	@param			{string} keyName Name of key to use as inverted index
--	@return			{table} Resultant table
function table.invertIndex(t, keyName)
	assert(type(t) == 'table', 'table.invertIndex(t, keyName): t must be a table')
	local temp = {}
	for k, v in pairs(t) do
		local keyValue = v[keyName]
		if (keyValue ~= nil) then
			if (temp[keyValue] == nil) then
				temp[keyValue] = {}
			end
			table.insert(temp[keyValue], v)
		end
	end
	return temp
end

---	Loads a copy of a data table. Being a copy, it is no longer readonly.
--	@function		p.loadData
--	@param			{string} t Location of data table ([[Module:<Module>/data]] usually)
--	@return			{table} Copy of data table
function table.loadData(t)
	return table.deepCopy(mw.loadData(t))
end

---	Sorts an array.
--	@function		p.sort
--	@param			{table} t Array-like table to be sorted
--	@param[opt]		{function} f Comparator function that takes in two arguments and returns a boolean;
--							   if omitted, uses default less-than operation when comparing two values
--	@return			{table} Sorted table for function chaining or tail call
function table.sort(t, f)
	table.__sort(t, f)
	return t
end

---	Copying key-value pairs to target table from reference table.
--	Assumes that tables only contain table entries. Keys that are already in target table
--	will not be overrided with data from reference table.
--	@function		p.copyKeyValues
--	@param			{table} targetTable Table to be modified
--	@param			{table} refTable Reference table
--	@param			{table} keyTable Table of key names to copy within each table entry
--	@return			{table} Modified target table
function table.copyKeyValues(targetTable, refTable, keyTable)
	assert(type(targetTable) == 'table' and type(refTable) == 'table' and type(keyTable) == 'table',
		'table.copyKeyValues(targetTable, refTable, keyTable): all arguments must be table types')
	for k, v in pairs(targetTable) do
		local targetTableEntry = targetTable[k]
		local refTableEntry = refTable[k]
		for _, key in ipairs(keyTable) do
			if (targetTable[key] == nil) then
				if (type(refTableEntry[key]) == 'table') then
					targetTableEntry[key] = table.deepCopy(refTableEntry[key])
				else
					targetTableEntry[key] = refTableEntry[key]
				end
			end
		end
	end
	return targetTable
end

---	Iterator sorted by keys.<br />
--	For example, a table that looked something like<br />
--	`data = {["Cat"] = 5, ["Bat"] = 4, ["Hat"] = 7 }`<br />
--	then<br />
--	`for k, v in skpairs(data) do`<br />
--	would loop through:<br />
--	k="Bat" v=4;<br />
--	k="Cat" v=5;<br />
--	k="Hat" v=7 <br />
--	redone by [[user:gigamicro]]
--	@function		table.skpairs
--	@param			{table} t A table to be sorted
--	@param[opt]		{boolean or function} sortType If true, sort by descending order; ascending otherwise; can also pass a function
--	@return			{function} For loop initialising values
--	@return			{table} Two element table with table values, the first maps keys to their array index and the second is an array of key names
--	@return			{string} Starting key
function table.skpairs(t, sortType)
	if type(t) ~= 'table' then error('table.skpairs(t[, sortTable]): t must be a table',2) end
	
	local keys = {}
	for k in pairs(t) do keys[#keys + 1] = k end
	
	if type(sortType) == 'function' then
		table.sort(keys, sortType)--custom sort (always applied to keys)
	elseif sortType then--descending
		table.sort(keys, function(a, b) return a > b end)
	else
		table.sort(keys)--implicit <, function(a, b) return a < b end)>
	end
	
	local keysIndex = {}
	for i, k in ipairs(keys) do
		keysIndex[k] = i
	end
	
	return function(t, k)
		local key = t.k[ (t.i[k] or 0)+1 ]
		return key, t.t[key]
	end, {i=keysIndex, k=keys, t=t}, startingkey
end

---	Returns the number of elements/entries in a table.
--	If you want to only get the number of number indexed elements use the '#' 
--	operator or table.indexCount().
--	@function		table.size
--	@param			{table} table A table with no explicit nil values
--	@return			{number} The size of table, ignoring keys with nil values and 
--							 nil values themselves
function table.size(t)
	assert(type(t) == 'table', 'table.size(t): t must be a table')
	local count = 0
	for k, v in pairs(t) do
		count = count + 1
	end
	return count
end

---	Returns the number of number indexed elements in a table as well as the highest number index.
--	@function		table.indexCount
--	@param			{table} t A table with no explicit nil values
--	@return			{number} The number of indexed elements in a table; 
--							 if table is not of type 'table' then return nil
--	@return			{number} Largest index (not necessarily the same as count since tables can be non-contiguous arrays)
function table.indexCount(t)
	assert(type(t) == 'table', 'table.indexCount(t): t must be a table')
	local count, max = 0, nil
	for i in ipairs(t) do count, max = count + 1, i end
	return count, max
end

---	Sorts a table based on the listed column.
--	@function		table.tableSort
--	@param			{table} t Table to be sorted
--	@param			{string} sortCol Name of column to be sorted by
--	@param			{boolean} sortAscend If true, sorts in ascending order by specified column; false otherwise
--	@return			{table} Sorted table
function table.tableSort(t, sortCol, sortAscend)
	assert(type(t) == 'table', 'table.tableSort(t, sortCol, sortAscend): t must be a table')
	return table.sort(t, 
		sortAscend 
		and function(a, b) return a[sortCol] < b[sortCol] end
		or function(a, b) return a[sortCol] > b[sortCol] end
	)
end

---	Checks if a string value is in a table, acting as an array.
--	@function		table.contains
--	@param			{table} t A table to be searched through
--	@param			{string} item The element that is being searched for
--	@param			{boolean} ignoreCase If false, search is case-sensitive; true otherwise
--	@return			{boolean} True if element exists in table, false otherwise
--	@return			{number} The found element's index; nil if element is not found
--	@return			{string} Value that is found, same as item; nil if element is not found
function table.contains(t, item, ignoreCase)
	assert(type(t) == 'table', 'table.contains(t, item, ignoreCase): t must be a table')
	if (t == nil or item == nil) then 
		return false
	end
	for k, value in pairs(t) do
		if (value == item) or (ignoreCase and string.upper(value) == string.upper(item)) then
			return true, k, value
		end
	end
	
	return false
end

---	Filters tables into subsets.
--	<br/>auth: [[User:gigamicro]]
--	@function		table.filter
--	@param			{table} t table in which to search
--	@param			{string or function} search String to search in table's keys
--	@return			{table} A subset of the original table where search(k, v, t) is true
function table.filter(t, search)
	assert(type(t) == 'table', 'table.filter(t, search): t must be a table')
	search = ({
		string = function(k)
			--if type(k)~='string' then error('Key '..type(k)..' not string') end
			return string.find(k, search) and true or false
		end,
		number = nil and function(k, v, t)
			return 
		end,
		table = nil and function(k, v, t)
		end,
	})[type(search)] or search

	if type(search) ~= 'function' then return end
	
	local out = {}
	for k, v in pairs(t) do
		if search(k, v, t) then
			out[k] = v
		end
	end
	return out
end

---	Stores multiple return values into a table, similar to <code>table.pack</code> in Lua 5.2
--	@function		table.pack
--	@param			{...} ... Any number of returned values regardless of type
--	@return			{table} An array-like table containing the passed in arguments in the order that they are returned
function table.pack(...)
	return { n = select("#", ...), ... }
end

return table