<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
	<id>https://dicionario.advogadocompleto.com/index.php?action=history&amp;feed=atom&amp;title=M%C3%B3dulo%3ATableTools</id>
	<title>Módulo:TableTools - Histórico de revisão</title>
	<link rel="self" type="application/atom+xml" href="https://dicionario.advogadocompleto.com/index.php?action=history&amp;feed=atom&amp;title=M%C3%B3dulo%3ATableTools"/>
	<link rel="alternate" type="text/html" href="https://dicionario.advogadocompleto.com/index.php?title=M%C3%B3dulo:TableTools&amp;action=history"/>
	<updated>2026-05-15T18:02:27Z</updated>
	<subtitle>Histórico de revisões para esta página neste wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://dicionario.advogadocompleto.com/index.php?title=M%C3%B3dulo:TableTools&amp;diff=231&amp;oldid=prev</id>
		<title>Itaymbere: Criou página com &#039;-------------------------------------------------------------------------------- --                                   TableTools                               -- --                                                                            -- -- Este módulo inclui várias funções para lidar com tabelas Lua.              -- -- É um metamódulo, destinado a ser chamado a partir de outros módulos Lua, e -- -- não deve ser chamado diretamente a partir de &quot;#invoke&quot;....&#039;</title>
		<link rel="alternate" type="text/html" href="https://dicionario.advogadocompleto.com/index.php?title=M%C3%B3dulo:TableTools&amp;diff=231&amp;oldid=prev"/>
		<updated>2026-03-29T20:08:10Z</updated>

		<summary type="html">&lt;p&gt;Criou página com &amp;#039;-------------------------------------------------------------------------------- --                                   TableTools                               -- --                                                                            -- -- Este módulo inclui várias funções para lidar com tabelas Lua.              -- -- É um metamódulo, destinado a ser chamado a partir de outros módulos Lua, e -- -- não deve ser chamado diretamente a partir de &amp;quot;#invoke&amp;quot;....&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Página nova&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                                   TableTools                               --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- Este módulo inclui várias funções para lidar com tabelas Lua.              --&lt;br /&gt;
-- É um metamódulo, destinado a ser chamado a partir de outros módulos Lua, e --&lt;br /&gt;
-- não deve ser chamado diretamente a partir de &amp;quot;#invoke&amp;quot;.                    --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&amp;#039;libraryUtil&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Define variáveis e funções usadas com frequência.&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;
--------------------------------------------------------------------------------&lt;br /&gt;
-- isPositiveInteger&lt;br /&gt;
--&lt;br /&gt;
-- Esta função retorna &amp;quot;true&amp;quot; se o valor fornecido for um número inteiro &lt;br /&gt;
-- positivo e &amp;quot;false&amp;quot; se não. Embora não opere em tabelas, ela é incluída aqui &lt;br /&gt;
-- porque ela é útil para determinar se uma determinada chave de tabela está na &lt;br /&gt;
-- parte de arranjo ou na parte de &amp;#039;hash&amp;#039; de uma tabela.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.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;
-- isNan&lt;br /&gt;
--&lt;br /&gt;
-- Essa função retorna &amp;quot;true&amp;quot; se o número fornecido for um valor de &amp;quot;NaN&amp;quot; e &lt;br /&gt;
-- &amp;quot;false&amp;quot; se não. Embora não opere em tabelas, ela é incluída aqui porque ela &lt;br /&gt;
-- é útil para determinar se um valor pode ser uma chave de tabela válida. Lua &lt;br /&gt;
-- irá gerar um erro se um &amp;quot;NaN&amp;quot; for usado como uma chave de tabela.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.isNan(v)&lt;br /&gt;
	return type(v) == &amp;#039;number&amp;#039; and v ~= v&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- shallowClone&lt;br /&gt;
--&lt;br /&gt;
-- Essa função retorna um clone de uma tabela. O valor retornado é uma nova &lt;br /&gt;
-- tabela, mas todas as subtabelas e funções são compartilhadas. Os metamétodos &lt;br /&gt;
-- são respeitados, mas a tabela retornada não terá metatabela própria.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.shallowClone(t)&lt;br /&gt;
	checkType(&amp;#039;shallowClone&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&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;
-- removeDuplicates&lt;br /&gt;
--&lt;br /&gt;
-- Essa função remove os valores duplicados de um arranjo. As chaves de  &lt;br /&gt;
-- números inteiros que não são positivos são ignoradas. O valor mais antigo é &lt;br /&gt;
-- mantido e todos os valores duplicados subsequentes são removidos, mas caso &lt;br /&gt;
-- não, a ordem do arranjo permanece inalterada.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.removeDuplicates(arr)&lt;br /&gt;
	checkType(&amp;#039;removeDuplicates&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local ret, exists = {}, {}&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if isNan(v) then&lt;br /&gt;
			-- Os &amp;quot;NaN&amp;quot;s não podem ser chaves de tabela e também são únicos,&lt;br /&gt;
			-- portanto não precisamos verificar a existência.&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
		elseif not exists[v] then&lt;br /&gt;
			ret[#ret + 1] = v&lt;br /&gt;
			exists[v] = true&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;
-- numKeys&lt;br /&gt;
--&lt;br /&gt;
-- Essa função pega uma tabela e retorna um arranjo contendo os números &lt;br /&gt;
-- de quaisquer chaves numéricas que tenham valores que não são nulos,&lt;br /&gt;
-- classificados em ordem numérica.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.numKeys(t)&lt;br /&gt;
	checkType(&amp;#039;numKeys&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local isPositiveInteger = p.isPositiveInteger&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		if isPositiveInteger(k) then&lt;br /&gt;
			nums[#nums + 1] = k&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;
-- affixNums&lt;br /&gt;
--&lt;br /&gt;
-- Essa função pega uma tabela e retorna um arranjo contendo os números &lt;br /&gt;
-- de chaves com o prefixo e sufixo especificados. Por exemplo, para a tabela&lt;br /&gt;
-- {a1 = &amp;#039;foo&amp;#039;, a3 = &amp;#039;bar&amp;#039;, a6 = &amp;#039;baz&amp;#039;} e o prefixo &amp;quot;a&amp;quot;, &amp;quot;affixNums&amp;quot; retornará&lt;br /&gt;
-- {1, 3, 6}.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.affixNums(t, prefix, suffix)&lt;br /&gt;
	checkType(&amp;#039;affixNums&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;affixNums&amp;#039;, 2, prefix, &amp;#039;string&amp;#039;, true)&lt;br /&gt;
	checkType(&amp;#039;affixNums&amp;#039;, 3, suffix, &amp;#039;string&amp;#039;, true)&lt;br /&gt;
&lt;br /&gt;
	local function cleanPattern(s)&lt;br /&gt;
		-- Limpa um padrão (&amp;#039;pattern&amp;#039;) para que os caracteres mágicos &amp;quot;()%.[]*+-?^$&amp;quot;&lt;br /&gt;
		-- sejam interpretados literalmente.&lt;br /&gt;
		return s:gsub(&amp;#039;([%(%)%%%.%[%]%*%+%-%?%^%$])&amp;#039;, &amp;#039;%%%1&amp;#039;)&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;
	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[#nums + 1] = tonumber(num)&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;
-- numData&lt;br /&gt;
--&lt;br /&gt;
-- Dada uma tabela com chaves como {&amp;quot;foo1&amp;quot;, &amp;quot;bar1&amp;quot;, &amp;quot;foo2&amp;quot;, &amp;quot;baz2&amp;quot;}, essa &lt;br /&gt;
-- função retorna uma tabela de subtabelas no formato&lt;br /&gt;
-- {[1] = {foo = &amp;#039;texto&amp;#039;, bar = &amp;#039;texto&amp;#039;}, [2] = {foo = &amp;#039;texto&amp;#039;, baz = &amp;#039;texto&amp;#039;}}.&lt;br /&gt;
-- As chaves que não terminam com um número inteiro são armazenadas em uma &lt;br /&gt;
-- subtabela chamada &amp;quot;other&amp;quot;. A opção &amp;quot;compress&amp;quot; comprime a tabela para que &lt;br /&gt;
-- ela possa ser iterada com &amp;quot;ipairs&amp;quot;.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.numData(t, compress)&lt;br /&gt;
	checkType(&amp;#039;numData&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;numData&amp;#039;, 2, compress, &amp;#039;boolean&amp;#039;, true)&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(t) do&lt;br /&gt;
		local prefix, num = mw.ustring.match(tostring(k), &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;
				-- Os parâmetros posicionais correspondem à sequência em branco; &lt;br /&gt;
				-- coloca-os no início da subtabela.&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 = p.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;
-- compressSparseArray&lt;br /&gt;
--&lt;br /&gt;
-- Essa função pega um arranjo com um ou mais valores nulos e  &lt;br /&gt;
-- remove os valores nulos enquanto preserva a ordem, para que o arranjo&lt;br /&gt;
-- possa ser percorrido com segurança com &amp;quot;ipairs&amp;quot;.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.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 nums = p.numKeys(t)&lt;br /&gt;
	for _, num in ipairs(nums) do&lt;br /&gt;
		ret[#ret + 1] = t[num]&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- sparseIpairs&lt;br /&gt;
--&lt;br /&gt;
-- Esta função é uma iteradora para arranjos esparsos. Ela pode ser &lt;br /&gt;
-- usada como &amp;quot;ipairs&amp;quot;, mas pode manipular valores nulos.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.sparseIpairs(t)&lt;br /&gt;
	checkType(&amp;#039;sparseIpairs&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local nums = p.numKeys(t)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	local lim = #nums&lt;br /&gt;
	return function ()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if i &amp;lt;= lim then&lt;br /&gt;
			local key = nums[i]&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;
-- size&lt;br /&gt;
--&lt;br /&gt;
-- Essa função retorna o tamanho de uma tabela de pares chave/valor. Ela &lt;br /&gt;
-- também funcionará em arranjos, mas para arranjos é mais eficiente usar o &lt;br /&gt;
-- operador #.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.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;
local function defaultKeySort(item1, item2)&lt;br /&gt;
	-- número &amp;lt; sequência, então os números serão ordenados antes das &lt;br /&gt;
	-- sequências.&lt;br /&gt;
	local type1, type2 = type(item1), type(item2)&lt;br /&gt;
	if type1 ~= type2 then&lt;br /&gt;
		return type1 &amp;lt; type2&lt;br /&gt;
	elseif type1 == &amp;#039;table&amp;#039; or type1 == &amp;#039;boolean&amp;#039; or type1 == &amp;#039;function&amp;#039; then&lt;br /&gt;
		return tostring(item1) &amp;lt; tostring(item2)&lt;br /&gt;
	else&lt;br /&gt;
		return item1 &amp;lt; item2&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- keysToList&lt;br /&gt;
--&lt;br /&gt;
-- Essa função retorna um arranjo das chaves em uma tabela, ordenada usando&lt;br /&gt;
-- uma função de comparação padrão ou uma função &amp;quot;keySort&amp;quot; personalizada.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.keysToList(t, keySort, checked)&lt;br /&gt;
	if not checked then&lt;br /&gt;
		checkType(&amp;#039;keysToList&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
		checkTypeMulti(&amp;#039;keysToList&amp;#039;, 2, keySort, {&amp;#039;function&amp;#039;, &amp;#039;boolean&amp;#039;, &amp;#039;nil&amp;#039;})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local arr = {}&lt;br /&gt;
	local index = 1&lt;br /&gt;
	for k in pairs(t) do&lt;br /&gt;
		arr[index] = k&lt;br /&gt;
		index = index + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if keySort ~= false then&lt;br /&gt;
		keySort = type(keySort) == &amp;#039;function&amp;#039; and keySort or defaultKeySort&lt;br /&gt;
		table.sort(arr, keySort)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return arr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- sortedPairs&lt;br /&gt;
--&lt;br /&gt;
-- Essa função itera por meio de uma tabela, com as chaves ordenadas usando a &lt;br /&gt;
-- função &amp;quot;keysToList&amp;quot;. Se houver apenas chaves numéricas, &amp;quot;sparseIpairs&amp;quot; &lt;br /&gt;
-- provavelmente será mais eficiente.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.sortedPairs(t, keySort)&lt;br /&gt;
	checkType(&amp;#039;sortedPairs&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;sortedPairs&amp;#039;, 2, keySort, &amp;#039;function&amp;#039;, true)&lt;br /&gt;
&lt;br /&gt;
	local arr = p.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 = arr[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;
--------------------------------------------------------------------------------&lt;br /&gt;
-- isArray&lt;br /&gt;
--&lt;br /&gt;
-- Essa função retorna &amp;quot;true&amp;quot; se o valor fornecido for uma tabela e todas as   &lt;br /&gt;
-- chaves forem números inteiros consecutivos começando em 1.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.isArray(v)&lt;br /&gt;
	if type(v) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(v) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if v[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;
--------------------------------------------------------------------------------&lt;br /&gt;
-- isArrayLike&lt;br /&gt;
--&lt;br /&gt;
-- Essa função retorna &amp;quot;true&amp;quot; se o valor fornecido for iterável e todas as  &lt;br /&gt;
-- chaves forem números inteiros consecutivos começando em 1.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.isArrayLike(v)&lt;br /&gt;
	if not pcall(pairs, v) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for _ in pairs(v) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		if v[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;
--------------------------------------------------------------------------------&lt;br /&gt;
-- invert&lt;br /&gt;
--&lt;br /&gt;
-- Essa função transpõe as chaves e valores em um arranjo. Por exemplo, &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}. As duplicatas não são suportadas &lt;br /&gt;
-- (os valores dos resultados referem-se ao índice da última duplicata) e os  &lt;br /&gt;
-- valores &amp;quot;NaN&amp;quot; são ignorados.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.invert(arr)&lt;br /&gt;
	checkType(&amp;quot;invert&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local map = {}&lt;br /&gt;
	for i, v in ipairs(arr) do&lt;br /&gt;
		if not isNan(v) then&lt;br /&gt;
			map[v] = i&lt;br /&gt;
		end&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;
-- listToSet&lt;br /&gt;
--&lt;br /&gt;
-- Essa função cria um conjunto a partir da parte do arranjo da tabela. &lt;br /&gt;
-- A indexação do conjunto por qualquer um dos valores do arranjo retorna&lt;br /&gt;
-- &amp;quot;true&amp;quot;. Por exemplo, {&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;} -&amp;gt; {a = true, b = true, c = true}. Os&lt;br /&gt;
-- valores &amp;quot;NaN&amp;quot; são ignorados, pois Lua os considera como nunca sendo iguais &lt;br /&gt;
-- a qualquer valor (incluindo outros &amp;quot;NaN&amp;quot;s ou até eles mesmos).&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.listToSet(arr)&lt;br /&gt;
	checkType(&amp;quot;listToSet&amp;quot;, 1, arr, &amp;quot;table&amp;quot;)&lt;br /&gt;
	local isNan = p.isNan&lt;br /&gt;
	local set = {}&lt;br /&gt;
	for _, v in ipairs(arr) do&lt;br /&gt;
		if not isNan(v) then&lt;br /&gt;
			set[v] = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return set&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- deepCopy&lt;br /&gt;
--&lt;br /&gt;
-- Função de cópia profunda recursiva. Preserva as identidades das subtabelas.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
local function _deepCopy(orig, includeMetatable, already_seen)&lt;br /&gt;
	if type(orig) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		return orig&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- already_seen armazena as cópias das tabelas indexadas pela tabela &lt;br /&gt;
	-- original.&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;
	copy = {}&lt;br /&gt;
	already_seen[orig] = copy -- memoriza antes de qualquer recursão, para &lt;br /&gt;
							  -- evitar loops infinitos&lt;br /&gt;
	&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;
	&lt;br /&gt;
	if includeMetatable then&lt;br /&gt;
		local mt = getmetatable(orig)&lt;br /&gt;
		if mt ~= nil then&lt;br /&gt;
			setmetatable(copy, _deepCopy(mt, true, already_seen))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.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;
	return _deepCopy(orig, not noMetatable, already_seen or {})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- sparseConcat&lt;br /&gt;
--&lt;br /&gt;
-- Essa função concatena todos os valores na tabela que são indexados por &lt;br /&gt;
-- um número, em ordem.&lt;br /&gt;
-- &amp;quot;sparseConcat{a, nil, c, d}&amp;quot;  =&amp;gt;  &amp;quot;acd&amp;quot;&lt;br /&gt;
-- &amp;quot;sparseConcat{nil, b, c, d}&amp;quot;  =&amp;gt;  &amp;quot;bcd&amp;quot;&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.sparseConcat(t, sep, i, j)&lt;br /&gt;
	local arr = {}&lt;br /&gt;
&lt;br /&gt;
	local arr_i = 0&lt;br /&gt;
	for _, v in p.sparseIpairs(t) do&lt;br /&gt;
		arr_i = arr_i + 1&lt;br /&gt;
		arr[arr_i] = v&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(arr, sep, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- length&lt;br /&gt;
--&lt;br /&gt;
-- Essa função localiza o comprimento de um arranjo ou de um &lt;br /&gt;
-- quase-arranjo com chaves como &amp;quot;data1&amp;quot;, &amp;quot;data2&amp;quot; etc., usando um&lt;br /&gt;
-- algoritmo de pesquisa exponencial. Ela é semelhante ao operador #, mas pode &lt;br /&gt;
-- retornar um valor diferente quando houver lacunas na parte do arranjo&lt;br /&gt;
-- da tabela. Destina-se a ser usada em dados carregados com &amp;quot;mw.loadData&amp;quot;.  &lt;br /&gt;
-- Para outras tabelas, use #.&lt;br /&gt;
-- Observação: &amp;quot;#frame.args&amp;quot; no objeto &amp;quot;frame&amp;quot; sempre será definido como 0, &lt;br /&gt;
-- independentemente do número de parâmetros de predefinição sem nome, &lt;br /&gt;
-- portanto, use esta função para &amp;quot;frame.args&amp;quot;.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.length(t, prefix)&lt;br /&gt;
	-- Exige módulo embutido, de modo que &lt;br /&gt;
	-- [[Módulo:Exponential search]] que é necessário &lt;br /&gt;
	-- somente para esta função, não obtenha milhões de transclusões.&lt;br /&gt;
	local expSearch = require(&amp;quot;Módulo:Exponential search&amp;quot;)&lt;br /&gt;
	checkType(&amp;#039;length&amp;#039;, 1, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;length&amp;#039;, 2, prefix, &amp;#039;string&amp;#039;, true)&lt;br /&gt;
	return expSearch(function (i)&lt;br /&gt;
		local key&lt;br /&gt;
		if prefix then&lt;br /&gt;
			key = prefix .. tostring(i)&lt;br /&gt;
		else&lt;br /&gt;
			key = i&lt;br /&gt;
		end&lt;br /&gt;
		return t[key] ~= nil&lt;br /&gt;
	end) or 0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- inArray&lt;br /&gt;
--&lt;br /&gt;
-- Essa função Retorna &amp;quot;true&amp;quot; se &amp;quot;searchElement&amp;quot; for um membro do arranjo&lt;br /&gt;
-- e &amp;quot;false&amp;quot; se não. Equivalente a &amp;quot;array.includes(searchElement)&amp;quot; ou&lt;br /&gt;
-- &amp;quot;array.includes(searchElement, fromIndex)&amp;quot;, exceto que &amp;quot;fromIndex&amp;quot; é 1 &lt;br /&gt;
-- indexado&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.inArray(array, searchElement, fromIndex)&lt;br /&gt;
	checkType(&amp;quot;inArray&amp;quot;, 1, array, &amp;quot;table&amp;quot;)&lt;br /&gt;
	-- se &amp;quot;searchElement&amp;quot; for nulo, erro?&lt;br /&gt;
&lt;br /&gt;
	fromIndex = tonumber(fromIndex)&lt;br /&gt;
	if fromIndex then&lt;br /&gt;
		if (fromIndex &amp;lt; 0) then&lt;br /&gt;
			fromIndex = #array + fromIndex + 1&lt;br /&gt;
		end&lt;br /&gt;
		if fromIndex &amp;lt; 1 then fromIndex = 1 end&lt;br /&gt;
		for _, v in ipairs({unpack(array, fromIndex)}) do&lt;br /&gt;
			if v == searchElement then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for _, v in pairs(array) do&lt;br /&gt;
			if v == searchElement then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- merge&lt;br /&gt;
--&lt;br /&gt;
-- Dados os arranjos, retorna um arranjo contendo os elementos de cada arranjo &lt;br /&gt;
-- de entrada em sequência.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.merge(...)&lt;br /&gt;
	local arrays = {...}&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for i, arr in ipairs(arrays) do&lt;br /&gt;
		checkType(&amp;#039;merge&amp;#039;, i, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
		for _, v in ipairs(arr) do&lt;br /&gt;
			ret[#ret + 1] = v&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;
-- extend&lt;br /&gt;
--&lt;br /&gt;
-- Estende o primeiro arranjo no lugar anexando todos os elementos do segundo&lt;br /&gt;
-- arranjo.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.extend(arr1, arr2)&lt;br /&gt;
	checkType(&amp;#039;extend&amp;#039;, 1, arr1, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;extend&amp;#039;, 2, arr2, &amp;#039;table&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	for _, v in ipairs(arr2) do&lt;br /&gt;
		arr1[#arr1 + 1] = v&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Itaymbere</name></author>
	</entry>
</feed>