<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Atable</id>
	<title>Module:table - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Atable"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;action=history"/>
	<updated>2026-04-05T23:03:43Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=474897&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=474897&amp;oldid=prev"/>
		<updated>2025-11-04T17:47:13Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:47, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=474896&amp;oldid=prev</id>
		<title>wikt&gt;Theknightwho: getNested() moved to Module:table/getNested and setNested() moved to Module:table/setNested.</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=474896&amp;oldid=prev"/>
		<updated>2025-05-14T21:57:51Z</updated>

		<summary type="html">&lt;p&gt;getNested() moved to &lt;a href=&quot;/wiki/Module:table/getNested&quot; title=&quot;Module:table/getNested&quot;&gt;Module:table/getNested&lt;/a&gt; and setNested() moved to &lt;a href=&quot;/wiki/Module:table/setNested&quot; title=&quot;Module:table/setNested&quot;&gt;Module:table/setNested&lt;/a&gt;.&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:table&amp;amp;diff=474896&amp;amp;oldid=410426&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>wikt&gt;Theknightwho</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=410426&amp;oldid=prev</id>
		<title>Sware at 19:50, 8 January 2025</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=410426&amp;oldid=prev"/>
		<updated>2025-01-08T19:50:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:50, 8 January 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l97&quot;&gt;Line 97:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 97:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return copy&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return copy&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;end&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;function export.shallowcopy(orig, raw)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;	return export.shallowCopy(orig, raw)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=410293&amp;oldid=prev</id>
		<title>Sware at 12:42, 8 January 2025</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=410293&amp;oldid=prev"/>
		<updated>2025-01-08T12:42:14Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:table&amp;amp;diff=410293&amp;amp;oldid=380090&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=380090&amp;oldid=prev</id>
		<title>Sware at 23:02, 29 August 2024</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=380090&amp;oldid=prev"/>
		<updated>2024-08-29T23:02:13Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:table&amp;amp;diff=380090&amp;amp;oldid=376376&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=376376&amp;oldid=prev</id>
		<title>Sware at 10:15, 14 August 2024</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=376376&amp;oldid=prev"/>
		<updated>2024-08-14T10:15:54Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:table&amp;amp;diff=376376&amp;amp;oldid=302590&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=302590&amp;oldid=prev</id>
		<title>Sware at 14:50, 3 May 2023</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=302590&amp;oldid=prev"/>
		<updated>2023-05-03T14:50:34Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:table&amp;amp;diff=302590&amp;amp;oldid=214143&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=214143&amp;oldid=prev</id>
		<title>Sware at 21:30, 23 December 2020</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=214143&amp;oldid=prev"/>
		<updated>2020-12-23T21:30:46Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://linguifex.com/w/index.php?title=Module:table&amp;amp;diff=214143&amp;amp;oldid=171721&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:table&amp;diff=171721&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;--[[ ------------------------------------------------------------------------------------ --                      table (formerly TableTools)                               --...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:table&amp;diff=171721&amp;oldid=prev"/>
		<updated>2019-11-09T15:21:47Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;--[[ ------------------------------------------------------------------------------------ --                      table (formerly TableTools)                               --...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--                      table (formerly TableTools)                               --&lt;br /&gt;
--                                                                                --&lt;br /&gt;
-- This module inclcudes a number of functions for dealing with Lua tables.        --&lt;br /&gt;
-- It is a meta-module, meant to be called from other Lua modules, and should     --&lt;br /&gt;
-- not be called directly from #invoke.                                           --&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Inserting new values into a table using a local &amp;quot;index&amp;quot; variable, which is&lt;br /&gt;
	incremented each time, is faster than using &amp;quot;table.insert(t, x)&amp;quot; or&lt;br /&gt;
	&amp;quot;t[#t + 1] = x&amp;quot;. See the talk page.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&amp;#039;libraryUtil&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local export = {}&lt;br /&gt;
&lt;br /&gt;
-- Define often-used variables and functions.&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
local infinity = math.huge&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
local function _check(funcName, expectType)&lt;br /&gt;
	if type(expectType) == &amp;quot;string&amp;quot; then&lt;br /&gt;
		return function(argIndex, arg, nilOk)&lt;br /&gt;
			checkType(funcName, argIndex, arg, expectType, nilOk)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return function(argIndex, arg, expectType, nilOk)&lt;br /&gt;
			if type(expectType) == &amp;quot;table&amp;quot; then&lt;br /&gt;
				checkTypeMulti(funcName, argIndex, arg, expectType, nilOk)&lt;br /&gt;
			else&lt;br /&gt;
				checkType(funcName, argIndex, arg, expectType, nilOk)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isPositiveInteger&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given value is a positive integer, and false&lt;br /&gt;
-- if not. Although it doesn&amp;#039;t operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a given table key is in the array part or the&lt;br /&gt;
-- hash part of a table.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.isPositiveInteger(v)&lt;br /&gt;
	return type(v) == &amp;#039;number&amp;#039; and v &amp;gt;= 1 and floor(v) == v and v &amp;lt; infinity&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- isNan&lt;br /&gt;
--&lt;br /&gt;
-- This function returns true if the given number is a NaN value, and false&lt;br /&gt;
-- if not. Although it doesn&amp;#039;t operate on tables, it is included here as it is&lt;br /&gt;
-- useful for determining whether a value can be a valid table key. Lua will&lt;br /&gt;
-- generate an error if a NaN is used as a table key.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.isNan(v)&lt;br /&gt;
	if type(v) == &amp;#039;number&amp;#039; and tostring(v) == &amp;#039;-nan&amp;#039; then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- shallowClone&lt;br /&gt;
--&lt;br /&gt;
-- This returns a clone of a table. The value returned is a new table, but all&lt;br /&gt;
-- subtables and functions are shared. Metamethods are respected, but the returned&lt;br /&gt;
-- table will have no metatable of its own.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.shallowClone(t)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		ret[k] = v&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Shallow copy&lt;br /&gt;
]]&lt;br /&gt;
function export.shallowcopy(orig)&lt;br /&gt;
	local orig_type = type(orig)&lt;br /&gt;
	local copy&lt;br /&gt;
	if orig_type == &amp;#039;table&amp;#039; then&lt;br /&gt;
		copy = {}&lt;br /&gt;
		for orig_key, orig_value in pairs(orig) do&lt;br /&gt;
			copy[orig_key] = orig_value&lt;br /&gt;
		end&lt;br /&gt;
	else -- number, string, boolean, etc&lt;br /&gt;
		copy = orig&lt;br /&gt;
	end&lt;br /&gt;
	return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Recursive deep copy function&lt;br /&gt;
	Equivalent to mw.clone?&lt;br /&gt;
]]&lt;br /&gt;
local function deepcopy(orig, includeMetatable, already_seen)&lt;br /&gt;
	-- Stores copies of tables indexed by the original table.&lt;br /&gt;
	already_seen = already_seen or {}&lt;br /&gt;
	&lt;br /&gt;
	local copy = already_seen[orig]&lt;br /&gt;
	if copy ~= nil then&lt;br /&gt;
		return copy&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if type(orig) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		copy = {}&lt;br /&gt;
		for orig_key, orig_value in pairs(orig) do&lt;br /&gt;
			copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)&lt;br /&gt;
		end&lt;br /&gt;
		already_seen[orig] = copy&lt;br /&gt;
		&lt;br /&gt;
		if includeMetatable then&lt;br /&gt;
			local mt = getmetatable(orig)&lt;br /&gt;
			if mt ~= nil then&lt;br /&gt;
				local mt_copy = deepcopy(mt, includeMetatable, already_seen)&lt;br /&gt;
				setmetatable(copy, mt_copy)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else -- number, string, boolean, etc&lt;br /&gt;
		copy = orig&lt;br /&gt;
	end&lt;br /&gt;
	return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.deepcopy(orig, noMetatable, already_seen)&lt;br /&gt;
	checkType(&amp;quot;deepcopy&amp;quot;, 3, already_seen, &amp;quot;table&amp;quot;, true)&lt;br /&gt;
	&lt;br /&gt;
	return deepcopy(orig, not noMetatable, already_seen)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- removeDuplicates&lt;br /&gt;
--&lt;br /&gt;
-- This removes duplicate values from an array. Non-positive-integer keys are&lt;br /&gt;
-- ignored. The earliest value is kept, and all subsequent duplicate values are&lt;br /&gt;
-- removed, but otherwise the array order is unchanged.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.removeDuplicates(t)&lt;br /&gt;
	checkType(&amp;#039;removeDuplicates&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local isNan = export.isNan&lt;br /&gt;
	local ret, exists = {}, {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for _, v in ipairs(t) do&lt;br /&gt;
		if isNan(v) then&lt;br /&gt;
			-- NaNs can&amp;#039;t be table keys, and they are also unique, so we don&amp;#039;t need to check existence.&lt;br /&gt;
			ret[index] = v&lt;br /&gt;
			index = index + 1&lt;br /&gt;
		else&lt;br /&gt;
			if not exists[v] then&lt;br /&gt;
				ret[index] = v&lt;br /&gt;
				index = index + 1&lt;br /&gt;
				exists[v] = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numKeys&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of any numerical&lt;br /&gt;
-- keys that have non-nil values, sorted in numerical order.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.numKeys(t, checked)&lt;br /&gt;
	if not checked then&lt;br /&gt;
		checkType(&amp;#039;numKeys&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	local isPositiveInteger = export.isPositiveInteger&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for k, _ in pairs(t) do&lt;br /&gt;
		if isPositiveInteger(k) then&lt;br /&gt;
			nums[index] = k&lt;br /&gt;
			index = index + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.maxIndex(t)&lt;br /&gt;
	checkType(&amp;#039;maxIndex&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local positiveIntegerKeys = export.numKeys(t)&lt;br /&gt;
	if positiveIntegerKeys[1] then&lt;br /&gt;
		return math.max(unpack(positiveIntegerKeys))&lt;br /&gt;
	else&lt;br /&gt;
		return 0 -- ???&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- affixNums&lt;br /&gt;
--&lt;br /&gt;
-- This takes a table and returns an array containing the numbers of keys with the&lt;br /&gt;
-- specified prefix and suffix.&lt;br /&gt;
-- affixNums({a1 = &amp;#039;foo&amp;#039;, a3 = &amp;#039;bar&amp;#039;, a6 = &amp;#039;baz&amp;#039;}, &amp;quot;a&amp;quot;)&lt;br /&gt;
--		↓&lt;br /&gt;
-- {1, 3, 6}.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.affixNums(t, prefix, suffix)&lt;br /&gt;
	local check = _check(&amp;#039;affixNums&amp;#039;)&lt;br /&gt;
	check(1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	check(2, prefix, &amp;#039;string&amp;#039;, true)&lt;br /&gt;
	check(3, suffix, &amp;#039;string&amp;#039;, true)&lt;br /&gt;
	&lt;br /&gt;
	local function cleanPattern(s)&lt;br /&gt;
		-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.&lt;br /&gt;
		s = s:gsub(&amp;#039;([%(%)%%%.%[%]%*%+%-%?%^%$])&amp;#039;, &amp;#039;%%%1&amp;#039;)&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	prefix = prefix or &amp;#039;&amp;#039;&lt;br /&gt;
	suffix = suffix or &amp;#039;&amp;#039;&lt;br /&gt;
	prefix = cleanPattern(prefix)&lt;br /&gt;
	suffix = cleanPattern(suffix)&lt;br /&gt;
	local pattern = &amp;#039;^&amp;#039; .. prefix .. &amp;#039;([1-9]%d*)&amp;#039; .. suffix .. &amp;#039;$&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for k, _ in pairs(t) do&lt;br /&gt;
		if type(k) == &amp;#039;string&amp;#039; then&lt;br /&gt;
			local num = mw.ustring.match(k, pattern)&lt;br /&gt;
			if num then&lt;br /&gt;
				nums[index] = tonumber(num)&lt;br /&gt;
				index = index + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- numData&lt;br /&gt;
--&lt;br /&gt;
-- Given a table with keys like (&amp;quot;foo1&amp;quot;, &amp;quot;bar1&amp;quot;, &amp;quot;foo2&amp;quot;, &amp;quot;baz2&amp;quot;), returns a table&lt;br /&gt;
-- of subtables in the format&lt;br /&gt;
-- { [1] = {foo = &amp;#039;text&amp;#039;, bar = &amp;#039;text&amp;#039;}, [2] = {foo = &amp;#039;text&amp;#039;, baz = &amp;#039;text&amp;#039;} }&lt;br /&gt;
-- Keys that don&amp;#039;t end with an integer are stored in a subtable named &amp;quot;other&amp;quot;.&lt;br /&gt;
-- The compress option compresses the table so that it can be iterated over with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.numData(t, compress)&lt;br /&gt;
	local check = _check(&amp;#039;numData&amp;#039;)&lt;br /&gt;
	check(1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	check(2, compress, &amp;#039;boolean&amp;#039;, true)&lt;br /&gt;
	&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		local prefix, num = tostring(k):match(&amp;#039;^([^0-9]*)([1-9][0-9]*)$&amp;#039;)&lt;br /&gt;
		if num then&lt;br /&gt;
			num = tonumber(num)&lt;br /&gt;
			local subtable = ret[num] or {}&lt;br /&gt;
			if prefix == &amp;#039;&amp;#039; then&lt;br /&gt;
				-- Positional parameters match the blank string; put them at the start of the subtable instead.&lt;br /&gt;
				prefix = 1&lt;br /&gt;
			end&lt;br /&gt;
			subtable[prefix] = v&lt;br /&gt;
			ret[num] = subtable&lt;br /&gt;
		else&lt;br /&gt;
			local subtable = ret.other or {}&lt;br /&gt;
			subtable[k] = v&lt;br /&gt;
			ret.other = subtable&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if compress then&lt;br /&gt;
		local other = ret.other&lt;br /&gt;
		ret = export.compressSparseArray(ret)&lt;br /&gt;
		ret.other = other&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- compressSparseArray&lt;br /&gt;
--&lt;br /&gt;
-- This takes an array with one or more nil values, and removes the nil values&lt;br /&gt;
-- while preserving the order, so that the array can be safely traversed with&lt;br /&gt;
-- ipairs.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.compressSparseArray(t)&lt;br /&gt;
	checkType(&amp;#039;compressSparseArray&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	local nums = export.numKeys(t)&lt;br /&gt;
	for _, num in ipairs(nums) do&lt;br /&gt;
		ret[index] = t[num]&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- sparseIpairs&lt;br /&gt;
--&lt;br /&gt;
-- This is an iterator for sparse arrays. It can be used like ipairs, but can&lt;br /&gt;
-- handle nil values.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.sparseIpairs(t)&lt;br /&gt;
	checkType(&amp;#039;sparseIpairs&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local nums = export.numKeys(t)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	return function()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local key = nums[i]&lt;br /&gt;
		if key then&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
-- size&lt;br /&gt;
--&lt;br /&gt;
-- This returns the size of a key/value pair table. It will also work on arrays,&lt;br /&gt;
-- but for arrays it is more efficient to use the # operator.&lt;br /&gt;
------------------------------------------------------------------------------------&lt;br /&gt;
--]]&lt;br /&gt;
function export.size(t)&lt;br /&gt;
	checkType(&amp;#039;size&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
-- This returns the length of a table, or the first integer key n counting from&lt;br /&gt;
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return&lt;br /&gt;
-- a different value when there are gaps in the array portion of the table.&lt;br /&gt;
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.&lt;br /&gt;
--]]&lt;br /&gt;
function export.length(t)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	repeat&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	until t[i] == nil&lt;br /&gt;
	return i - 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Takes table and a value to be found.&lt;br /&gt;
If the value is in the array portion of the table, return true.&lt;br /&gt;
If the value is in the hashmap or not in the table, return false.&lt;br /&gt;
]]&lt;br /&gt;
function export.contains(list, x)&lt;br /&gt;
	for _, v in ipairs(list) do&lt;br /&gt;
		if v == x then return true end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Recursively compare two values that may be tables, including tables with&lt;br /&gt;
nested tables as values. Return true if both values are structurally equal.&lt;br /&gt;
Note that this handles arbitary levels of nesting. If all tables are known&lt;br /&gt;
to be lists (with only integral keys), use export.deepEqualsList, which will&lt;br /&gt;
be more efficient.&lt;br /&gt;
&lt;br /&gt;
NOTE: This is *NOT* smart enough to properly handle cycles; in such a case, it&lt;br /&gt;
will get into an infinite loop.&lt;br /&gt;
]]&lt;br /&gt;
function export.deepEquals(x, y)&lt;br /&gt;
    if type(x) == &amp;quot;table&amp;quot; and type(y) == &amp;quot;table&amp;quot; then&lt;br /&gt;
    	-- Two tables are the same if they have the same number of elements&lt;br /&gt;
    	-- and all keys that are present in one of the tables compare equal&lt;br /&gt;
    	-- to the corresponding keys in the other table, using structural&lt;br /&gt;
    	-- comparison.&lt;br /&gt;
    	local sizex = 0&lt;br /&gt;
        for key, value in pairs(x) do&lt;br /&gt;
            if not export.deepEquals(value, y[key]) then&lt;br /&gt;
                return false&lt;br /&gt;
            end&lt;br /&gt;
            sizex = sizex + 1&lt;br /&gt;
        end&lt;br /&gt;
        local sizey = export.size(y)&lt;br /&gt;
        if sizex ~= sizey then&lt;br /&gt;
            return false&lt;br /&gt;
        end &lt;br /&gt;
        return true&lt;br /&gt;
    end&lt;br /&gt;
    return x == y&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Recursively compare two values that may be lists (i.e. tables with integral&lt;br /&gt;
keys), including lists with nested lists as values. Return true if both values&lt;br /&gt;
are structurally equal. Note that this handles arbitary levels of nesting.&lt;br /&gt;
Results are undefined if tables with non-integral keys are present anywhere in&lt;br /&gt;
either structure; if that may be the case, use export.deepEquals, which will&lt;br /&gt;
handle such tables correctly but be less efficient on lists than&lt;br /&gt;
export.deepEqualsList.&lt;br /&gt;
&lt;br /&gt;
NOTE: This is *NOT* smart enough to properly handle cycles; in such a case, it&lt;br /&gt;
will get into an infinite loop.&lt;br /&gt;
]]&lt;br /&gt;
function export.deepEqualsList(x, y)&lt;br /&gt;
    if type(x) == &amp;quot;table&amp;quot; and type(y) == &amp;quot;table&amp;quot; then&lt;br /&gt;
        if #x ~= #y then&lt;br /&gt;
            return false&lt;br /&gt;
        end &lt;br /&gt;
        for key, value in ipairs(x) do&lt;br /&gt;
            if not export.deepEqualsList(value, y[key]) then&lt;br /&gt;
                return false&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        return true&lt;br /&gt;
    end&lt;br /&gt;
    return x == y&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Finds key for specified value in a given table.&lt;br /&gt;
	Roughly equivalent to reversing the key-value pairs in the table –&lt;br /&gt;
		reversed_table = { [value1] = key1, [value2] = key2, ... }&lt;br /&gt;
	– and then returning reversed_table[valueToFind].&lt;br /&gt;
	&lt;br /&gt;
	The value can only be a string or a number&lt;br /&gt;
	(not nil, a boolean, a table, or a function).&lt;br /&gt;
	&lt;br /&gt;
	Only reliable if there is just one key with the specified value.&lt;br /&gt;
	Otherwise, the function returns the first key found,&lt;br /&gt;
	and the output is unpredictable.&lt;br /&gt;
]]&lt;br /&gt;
function export.keyFor(t, valueToFind)&lt;br /&gt;
	local check = _check(&amp;#039;keyFor&amp;#039;)&lt;br /&gt;
	check(1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	check(2, valueToFind, { &amp;#039;string&amp;#039;, &amp;#039;number&amp;#039; })&lt;br /&gt;
	&lt;br /&gt;
	for key, value in pairs(t) do&lt;br /&gt;
		if value == valueToFind then&lt;br /&gt;
			return key&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	The default sorting function used in export.keysToList if no keySort&lt;br /&gt;
	is defined.&lt;br /&gt;
]]&lt;br /&gt;
local function defaultKeySort(key1, key2)&lt;br /&gt;
	-- &amp;quot;number&amp;quot; &amp;lt; &amp;quot;string&amp;quot;, so numbers will be sorted before strings.&lt;br /&gt;
	local type1, type2 = type(key1), type(key2)&lt;br /&gt;
	if type1 ~= type2 then&lt;br /&gt;
		return type1 &amp;lt; type2&lt;br /&gt;
	else&lt;br /&gt;
		return key1 &amp;lt; key2&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Returns a list of the keys in a table, sorted using either the default&lt;br /&gt;
	table.sort function or a custom keySort function.&lt;br /&gt;
	If there are only numerical keys, numKeys is probably more efficient.&lt;br /&gt;
]]&lt;br /&gt;
function export.keysToList(t, keySort, checked)&lt;br /&gt;
	if not checked then&lt;br /&gt;
		local check = _check(&amp;#039;keysToList&amp;#039;)&lt;br /&gt;
		check(1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
		check(2, keySort, &amp;#039;function&amp;#039;, true)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local list = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for key, _ in pairs(t) do&lt;br /&gt;
		list[index] = key&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Place numbers before strings, otherwise sort using &amp;lt;.&lt;br /&gt;
	if not keySort then&lt;br /&gt;
		keySort = defaultKeySort&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	table.sort(list, keySort)&lt;br /&gt;
	&lt;br /&gt;
	return list&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Iterates through a table, with the keys sorted using the keysToList function.&lt;br /&gt;
	If there are only numerical keys, sparseIpairs is probably more efficient.&lt;br /&gt;
]]&lt;br /&gt;
function export.sortedPairs(t, keySort)&lt;br /&gt;
	local check = _check(&amp;#039;keysToList&amp;#039;)&lt;br /&gt;
	check(1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	check(2, keySort, &amp;#039;function&amp;#039;, true)&lt;br /&gt;
	&lt;br /&gt;
	local list = export.keysToList(t, keySort, true)&lt;br /&gt;
	&lt;br /&gt;
	local i = 0&lt;br /&gt;
	return function()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local key = list[i]&lt;br /&gt;
		if key ~= nil then&lt;br /&gt;
			return key, t[key]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.reverseIpairs(list)&lt;br /&gt;
	checkType(&amp;#039;reverse_ipairs&amp;#039;, 1, list, &amp;#039;table&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	local i = #list + 1&lt;br /&gt;
	return function()&lt;br /&gt;
		i = i - 1&lt;br /&gt;
		if list[i] ~= nil then&lt;br /&gt;
			return i, list[i]&lt;br /&gt;
		else&lt;br /&gt;
			return nil, nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
	Joins an array with serial comma and serial conjunction, normally &amp;quot;and&amp;quot;.&lt;br /&gt;
	An improvement on mw.text.listToText, which doesn&amp;#039;t properly handle serial&lt;br /&gt;
	commas.&lt;br /&gt;
	&lt;br /&gt;
	Options:&lt;br /&gt;
		- conj&lt;br /&gt;
			Conjunction to use; defaults to &amp;quot;and&amp;quot;.&lt;br /&gt;
		- italicizeConj&lt;br /&gt;
			Italicize conjunction: for [[Module:Template:also]]&lt;br /&gt;
		- dontTag&lt;br /&gt;
			Don&amp;#039;t tag the serial comma and serial &amp;quot;and&amp;quot;. For error messages, in&lt;br /&gt;
			which HTML cannot be used.&lt;br /&gt;
]=]&lt;br /&gt;
function export.serialCommaJoin(seq, options)&lt;br /&gt;
	local check = _check(&amp;quot;serialCommaJoin&amp;quot;, &amp;quot;table&amp;quot;)&lt;br /&gt;
	check(1, seq)&lt;br /&gt;
	check(2, options, true)&lt;br /&gt;
	&lt;br /&gt;
	local length = #seq&lt;br /&gt;
	&lt;br /&gt;
	if not options then&lt;br /&gt;
		options = {}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local conj&lt;br /&gt;
	if length &amp;gt; 1 then&lt;br /&gt;
		conj = options.conj or &amp;quot;and&amp;quot;&lt;br /&gt;
		if options.italicizeConj then&lt;br /&gt;
			conj = &amp;quot;&amp;#039;&amp;#039;&amp;quot; .. conj .. &amp;quot;&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if length == 0 then&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	elseif length == 1 then&lt;br /&gt;
		return seq[1] -- nothing to join&lt;br /&gt;
	elseif length == 2 then&lt;br /&gt;
		return seq[1] .. &amp;quot; &amp;quot; .. conj .. &amp;quot; &amp;quot; .. seq[2]&lt;br /&gt;
	else&lt;br /&gt;
		local comma = options.dontTag and &amp;quot;,&amp;quot; or &amp;#039;&amp;lt;span class=&amp;quot;serial-comma&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;#039;&lt;br /&gt;
		conj = options.dontTag and &amp;#039; &amp;#039; .. conj .. &amp;quot; &amp;quot; or &amp;#039;&amp;lt;span class=&amp;quot;serial-and&amp;quot;&amp;gt; &amp;#039; .. conj .. &amp;#039;&amp;lt;/span&amp;gt; &amp;#039;&lt;br /&gt;
		return table.concat(seq, &amp;quot;, &amp;quot;, 1, length - 1) ..&lt;br /&gt;
				comma .. conj .. seq[length]&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Concatenates all values in the table that are indexed by a number, in order.&lt;br /&gt;
	sparseConcat{ a, nil, c, d }  =&amp;gt;  &amp;quot;acd&amp;quot;&lt;br /&gt;
	sparseConcat{ nil, b, c, d }  =&amp;gt;  &amp;quot;bcd&amp;quot;&lt;br /&gt;
]]&lt;br /&gt;
function export.sparseConcat(t, sep, i, j)&lt;br /&gt;
	local list = {}&lt;br /&gt;
	&lt;br /&gt;
	local list_i = 0&lt;br /&gt;
	for _, v in export.sparseIpairs(t) do&lt;br /&gt;
		list_i = list_i + 1&lt;br /&gt;
		list[list_i] = v&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat(list, sep, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Values of numberic keys in array portion of table are reversed:&lt;br /&gt;
	{ &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { &amp;quot;c&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;a&amp;quot; }&lt;br /&gt;
--]]&lt;br /&gt;
function export.reverse(t)&lt;br /&gt;
	checkType(&amp;quot;reverse&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local new_t = {}&lt;br /&gt;
	local new_t_i = 1&lt;br /&gt;
	for i = #t, 1, -1 do&lt;br /&gt;
		new_t[new_t_i] = t[i]&lt;br /&gt;
		new_t_i = new_t_i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return new_t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.reverseConcat(t, sep, i, j)&lt;br /&gt;
	return table.concat(export.reverse(t), sep, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- { &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { a = 1, b = 2, c = 3 }&lt;br /&gt;
function export.invert(array)&lt;br /&gt;
	checkType(&amp;quot;invert&amp;quot;, 1, array, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local map = {}&lt;br /&gt;
	for i, v in ipairs(array) do&lt;br /&gt;
		map[v] = i&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return map&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	{ &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot; } -&amp;gt; { [&amp;quot;a&amp;quot;] = true, [&amp;quot;b&amp;quot;] = true, [&amp;quot;c&amp;quot;] = true }&lt;br /&gt;
--]]&lt;br /&gt;
function export.listToSet(t)&lt;br /&gt;
	checkType(&amp;quot;listToSet&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local set = {}&lt;br /&gt;
	for _, item in ipairs(t) do&lt;br /&gt;
		set[item] = true&lt;br /&gt;
	end&lt;br /&gt;
	return set&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	Returns true if all keys in the table are consecutive integers starting at 1.&lt;br /&gt;
--]]&lt;br /&gt;
function export.isArray(t)&lt;br /&gt;
	checkType(&amp;quot;isArray&amp;quot;, 1, t, &amp;quot;table&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(t) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if t[i] == nil then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
</feed>