<?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%3AArray</id>
	<title>Module:Array - 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%3AArray"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:Array&amp;action=history"/>
	<updated>2026-04-05T23:42:28Z</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:Array&amp;diff=214837&amp;oldid=prev</id>
		<title>Chrysophylax: Created page with &quot;local Array = {} local array_constructor  -- Copy table library so as not to unexpectedly change the behavior of code that -- uses it. local array_methods = mw.clone(table)  -...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:Array&amp;diff=214837&amp;oldid=prev"/>
		<updated>2021-01-02T04:24:51Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local Array = {} local array_constructor  -- Copy table library so as not to unexpectedly change the behavior of code that -- uses it. local array_methods = mw.clone(table)  -...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local Array = {}&lt;br /&gt;
local array_constructor&lt;br /&gt;
&lt;br /&gt;
-- Copy table library so as not to unexpectedly change the behavior of code that&lt;br /&gt;
-- uses it.&lt;br /&gt;
local array_methods = mw.clone(table)&lt;br /&gt;
&lt;br /&gt;
-- Create version of table.sort that returns the table.&lt;br /&gt;
array_methods.sort = function (t, comp)&lt;br /&gt;
	table.sort(t, comp)&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ipairs and unpack operate on arrays.&lt;br /&gt;
array_methods.ipairs = ipairs&lt;br /&gt;
array_methods.unpack = unpack&lt;br /&gt;
&lt;br /&gt;
function array_methods:type()&lt;br /&gt;
	local mt = getmetatable(self)&lt;br /&gt;
	return type(mt) == &amp;quot;table&amp;quot; and mt.__type or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function array_methods:adjustIndex(index)&lt;br /&gt;
	index = math.floor(index)&lt;br /&gt;
	if index &amp;lt; 0 then&lt;br /&gt;
		index = #self + index + 1&lt;br /&gt;
	end&lt;br /&gt;
	return index&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- string.sub-style slicing.&lt;br /&gt;
function array_methods:slice(i, j)&lt;br /&gt;
	if i == nil then&lt;br /&gt;
		i = 1&lt;br /&gt;
	elseif type(i) == &amp;quot;number&amp;quot; then&lt;br /&gt;
		i = self:adjust_index(i)&lt;br /&gt;
	else&lt;br /&gt;
		error(&amp;quot;Expected number, got &amp;quot; .. type(i))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if j == nil or type(j) == &amp;quot;number&amp;quot; then&lt;br /&gt;
		j = self:adjust_index(j or -1)&lt;br /&gt;
	else&lt;br /&gt;
		error(&amp;quot;Expected number, got &amp;quot; .. type(j))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local new_arr = array_constructor()&lt;br /&gt;
	local k = 0&lt;br /&gt;
	for index = i, j do&lt;br /&gt;
		k = k + 1&lt;br /&gt;
		new_arr[k] = self[index]&lt;br /&gt;
	end&lt;br /&gt;
	return new_arr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- A function to convert string key-table modules such&lt;br /&gt;
-- as [[Module:languages/data2]] into arrays.&lt;br /&gt;
-- &amp;quot;from&amp;quot; is a bad name.&lt;br /&gt;
-- field_for_key supplies the field name in which the&lt;br /&gt;
-- key will be stored.&lt;br /&gt;
local function to_array(map, field_for_key)&lt;br /&gt;
	m_table = m_table or require &amp;quot;Module:table&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	local arr = {}&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for key, val in pairs(map) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local new_val = m_table.shallowcopy(val)&lt;br /&gt;
		if field_for_key then&lt;br /&gt;
			new_val[field_for_key] = key&lt;br /&gt;
		end&lt;br /&gt;
		arr[i] = new_val&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return array_constructor(arr)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Functions from [[Module:table]] that operate on arrays or sparse arrays.&lt;br /&gt;
-- List copied from [[Module:table/documentation]].&lt;br /&gt;
local operate_on_array = {&lt;br /&gt;
	-- non-sparse&lt;br /&gt;
	&amp;quot;removeDuplicates&amp;quot;, &amp;quot;length&amp;quot;, &amp;quot;contains&amp;quot;, &amp;quot;serialCommaJoin&amp;quot;,&lt;br /&gt;
	&amp;quot;reverseIpairs&amp;quot;, &amp;quot;reverse&amp;quot;, &amp;quot;invert&amp;quot;, &amp;quot;listToSet&amp;quot;, &amp;quot;isArray&amp;quot;,&lt;br /&gt;
	-- sparse&lt;br /&gt;
	&amp;quot;numKeys&amp;quot;, &amp;quot;maxIndex&amp;quot;, &amp;quot;compressSparseArray&amp;quot;, &amp;quot;sparseIpairs&amp;quot;,&lt;br /&gt;
	-- tables in general&lt;br /&gt;
	&amp;quot;shallowcopy&amp;quot;, &amp;quot;deepcopy&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Not all of these operate on arrays.&lt;br /&gt;
local create_new_array = {&lt;br /&gt;
	-- Functions from [[Module:table]] that create an array.&lt;br /&gt;
	-- List copied from [[Module:table/documentation]].&lt;br /&gt;
	&amp;quot;removeDuplicates&amp;quot;, &amp;quot;numKeys&amp;quot;, &amp;quot;affixNums&amp;quot;, &amp;quot;compressSparseArray&amp;quot;,&lt;br /&gt;
	&amp;quot;keysToList&amp;quot;, &amp;quot;reverse&amp;quot;,&lt;br /&gt;
	-- Functions from [[Module:table]] that create an table.&lt;br /&gt;
	&amp;quot;shallowcopy&amp;quot;, &amp;quot;deepcopy&amp;quot;,&lt;br /&gt;
	-- Functions from [[Module:fun]] that create an array.&lt;br /&gt;
	&amp;quot;map&amp;quot;, &amp;quot;filter&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Functions from [[Module:fun]] that take an array in the second argument.&lt;br /&gt;
-- They just have to have the argument order reversed to work as methods of the&lt;br /&gt;
-- array object.&lt;br /&gt;
local second_argument_is_array = { &amp;quot;map&amp;quot;, &amp;quot;some&amp;quot;, &amp;quot;all&amp;quot;, &amp;quot;filter&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
-- Add aliases for the functions from [[Module:table]] whose names&lt;br /&gt;
-- contain &amp;quot;array&amp;quot; or &amp;quot;list&amp;quot;, which is redundant, and whose names don&amp;#039;t conform&lt;br /&gt;
-- to the usual camel case.&lt;br /&gt;
-- The key redirects to the value.&lt;br /&gt;
local alias_of = {&lt;br /&gt;
	compress = &amp;quot;compressSparseArray&amp;quot;, keys = &amp;quot;keysToList&amp;quot;, toSet = &amp;quot;listToSet&amp;quot;,&lt;br /&gt;
	deepCopy = &amp;quot;deepcopy&amp;quot;, shallowCopy = &amp;quot;shallowcopy&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function get_module_function(key, module, module_name)&lt;br /&gt;
	return module[key] &lt;br /&gt;
		or error(&amp;quot;No function named &amp;quot; .. tostring(key) .. &amp;quot; in Module:&amp;quot; .. module_name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function wrap_in_array_constructor(func)&lt;br /&gt;
	return function (...)&lt;br /&gt;
		return array_constructor(func(...))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function create_array_generating_func(key, module, module_name)&lt;br /&gt;
	return wrap_in_array_constructor(get_module_function(key, module, module_name))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function reverse_arguments(func)&lt;br /&gt;
	return function (a, b)&lt;br /&gt;
		return func(b, a, true)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function underscore_to_camel_case(str)&lt;br /&gt;
	if type(str) ~= &amp;quot;string&amp;quot; then return str end&lt;br /&gt;
	str = str:gsub(&amp;quot;_(.)&amp;quot;, string.upper)&lt;br /&gt;
	return str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local m_table, m_fun&lt;br /&gt;
local Array = {}&lt;br /&gt;
Array.__type = &amp;quot;array&amp;quot;&lt;br /&gt;
function Array:__index(key)&lt;br /&gt;
	if type(key) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Convert underscores to camel case: num_keys -&amp;gt; numKeys.&lt;br /&gt;
	key = underscore_to_camel_case(key)&lt;br /&gt;
	&lt;br /&gt;
	local val = array_methods[key]&lt;br /&gt;
	if val then&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	key = alias_of[key] or key&lt;br /&gt;
	&lt;br /&gt;
	local func&lt;br /&gt;
	m_table = m_table or require &amp;quot;Module:table&amp;quot;&lt;br /&gt;
	if m_table.contains(operate_on_array, key) then&lt;br /&gt;
		if m_table.contains(create_new_array, key) then&lt;br /&gt;
			func = create_array_generating_func(key, m_table, &amp;quot;table&amp;quot;)&lt;br /&gt;
		else&lt;br /&gt;
			func = m_table[key]&lt;br /&gt;
		end&lt;br /&gt;
	elseif m_table.contains(second_argument_is_array, key) then&lt;br /&gt;
		m_fun = m_fun or require &amp;quot;Module:fun&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		local raw_func = reverse_arguments(get_module_function(key, m_fun, &amp;quot;fun&amp;quot;))&lt;br /&gt;
		if m_table.contains(create_new_array, key) then&lt;br /&gt;
			func = wrap_in_array_constructor(raw_func)&lt;br /&gt;
		else&lt;br /&gt;
			func = raw_func&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if func then&lt;br /&gt;
		array_methods[key] = func&lt;br /&gt;
		return func&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__add(a, b)&lt;br /&gt;
	if type(a) == &amp;#039;table&amp;#039; and type(b) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		m_table = m_table or require &amp;quot;Module:table&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		local new_arr = array_constructor(m_table.shallowcopy(a))&lt;br /&gt;
		&lt;br /&gt;
		for _, val in ipairs(b) do&lt;br /&gt;
			new_arr:insert(val)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		return new_arr&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array:new(...)&lt;br /&gt;
	local arr&lt;br /&gt;
	if select(&amp;quot;#&amp;quot;, ...) == 1 and type((...)) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		arr = ...&lt;br /&gt;
		&lt;br /&gt;
		local mt = getmetatable(arr)&lt;br /&gt;
		-- If table has been loaded with mw.loadData, copy it to avoid the&lt;br /&gt;
		-- limitations of it being a virtual table.&lt;br /&gt;
		if mt and mt.mw_loadData then&lt;br /&gt;
			m_table = m_table or require &amp;quot;Module:table&amp;quot;&lt;br /&gt;
			arr = m_table.shallowcopy(arr)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		arr = { ... }&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(arr, self)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Declared as local above.&lt;br /&gt;
function array_constructor(...)&lt;br /&gt;
	return Array:new(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local array_generating_funcs = { from = to_array }&lt;br /&gt;
local Array_library_mt = {&lt;br /&gt;
	__call = Array.new, __index = array_generating_funcs&lt;br /&gt;
}&lt;br /&gt;
setmetatable(Array, Array_library_mt)&lt;br /&gt;
&lt;br /&gt;
function Array_library_mt:__index(key)&lt;br /&gt;
	key = underscore_to_camel_case(key)&lt;br /&gt;
	key = alias_of[key] or key&lt;br /&gt;
	&lt;br /&gt;
	if array_generating_funcs[key] then&lt;br /&gt;
		return array_generating_funcs[key]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	m_table = m_table or require &amp;quot;Module:table&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	if m_table.contains(create_new_array, key) then&lt;br /&gt;
		local func = create_array_generating_func(key, m_table, &amp;quot;table&amp;quot;)&lt;br /&gt;
		array_generating_funcs[key] = func&lt;br /&gt;
		return func&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return Array&lt;/div&gt;</summary>
		<author><name>Chrysophylax</name></author>
	</entry>
</feed>