<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.statsape.com/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3AArray</id>
	<title>模块:Array - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.statsape.com/index.php?action=history&amp;feed=atom&amp;title=%E6%A8%A1%E5%9D%97%3AArray"/>
	<link rel="alternate" type="text/html" href="https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:Array&amp;action=history"/>
	<updated>2026-04-03T23:10:20Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:Array&amp;diff=1520&amp;oldid=prev</id>
		<title>Zeroclanzhang：​创建页面，内容为“-- Imported from: https://runescape.wiki/w/Module:Array  local libraryUtil = require(&#039;libraryUtil&#039;) local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti  ---@class Array ---@operator call(any[]): Array ---@operator concat(any[]): Array ---@operator concat(number|string|function): string ---@operator unm: Array ---@operator add(number|number[]|Array): Array ---@operator sub(number|number[]|Array): Array ---@operator mul(numbe…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.statsape.com/index.php?title=%E6%A8%A1%E5%9D%97:Array&amp;diff=1520&amp;oldid=prev"/>
		<updated>2023-08-09T10:33:11Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“-- Imported from: https://runescape.wiki/w/Module:Array  local libraryUtil = require(&amp;#039;libraryUtil&amp;#039;) local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti  ---@class Array ---@operator call(any[]): Array ---@operator concat(any[]): Array ---@operator concat(number|string|function): string ---@operator unm: Array ---@operator add(number|number[]|Array): Array ---@operator sub(number|number[]|Array): Array ---@operator mul(numbe…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Imported from: https://runescape.wiki/w/Module:Array&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&amp;#039;libraryUtil&amp;#039;)&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
local checkTypeMulti = libraryUtil.checkTypeMulti&lt;br /&gt;
&lt;br /&gt;
---@class Array&lt;br /&gt;
---@operator call(any[]): Array&lt;br /&gt;
---@operator concat(any[]): Array&lt;br /&gt;
---@operator concat(number|string|function): string&lt;br /&gt;
---@operator unm: Array&lt;br /&gt;
---@operator add(number|number[]|Array): Array&lt;br /&gt;
---@operator sub(number|number[]|Array): Array&lt;br /&gt;
---@operator mul(number|number[]|Array): Array&lt;br /&gt;
---@operator div(number|number[]|Array): Array&lt;br /&gt;
---@operator pow(number|number[]|Array): Array&lt;br /&gt;
local Array = {&lt;br /&gt;
	pop = table.remove&lt;br /&gt;
}&lt;br /&gt;
Array.__index = Array&lt;br /&gt;
&lt;br /&gt;
setmetatable(Array, {&lt;br /&gt;
	__index = table,&lt;br /&gt;
	__call = function (_, arr)&lt;br /&gt;
		return Array.new(arr)&lt;br /&gt;
	end&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
-- function Array.__tostring(arr)&lt;br /&gt;
-- 	-- local dumpObject = require(&amp;#039;Module:Logger&amp;#039;).dumpObject&lt;br /&gt;
-- 	require &amp;#039;log&amp;#039;&lt;br /&gt;
-- 	local dumpObject = dumpObject&lt;br /&gt;
-- 	local mt = getmetatable(arr)&lt;br /&gt;
-- 	setmetatable(arr, nil)&lt;br /&gt;
-- 	local str = dumpObject(arr, {clean=true, collapseLimit=100})&lt;br /&gt;
-- 	setmetatable(arr, mt)&lt;br /&gt;
-- 	return str&lt;br /&gt;
-- end&lt;br /&gt;
&lt;br /&gt;
function Array.__concat(lhs, rhs)&lt;br /&gt;
	if type(lhs) == &amp;#039;table&amp;#039; and type(rhs) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		local res = {}&lt;br /&gt;
		for i = 1, #lhs do&lt;br /&gt;
			res[i] = lhs[i]&lt;br /&gt;
		end&lt;br /&gt;
		local l = #lhs&lt;br /&gt;
		for i = 1, #rhs do&lt;br /&gt;
			res[i + l] = rhs[i]&lt;br /&gt;
		end&lt;br /&gt;
		return setmetatable(res, getmetatable(lhs) or getmetatable(rhs))&lt;br /&gt;
	else&lt;br /&gt;
		return tostring(lhs) .. tostring(rhs)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__unm(arr)&lt;br /&gt;
	return Array.map(arr, function(x) return -x end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---@param lhs number|number[]|Array&lt;br /&gt;
---@param rhs number|number[]|Array&lt;br /&gt;
---@param funName string&lt;br /&gt;
---@param opName string&lt;br /&gt;
---@param fun fun(lhs: number, rhs: number): number&lt;br /&gt;
---@return Array&lt;br /&gt;
local function mathTemplate(lhs, rhs, funName, opName, fun)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.&amp;#039; .. funName, 1, lhs, {&amp;#039;number&amp;#039;, &amp;#039;table&amp;#039;})&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.&amp;#039; .. funName, 2, rhs, {&amp;#039;number&amp;#039;, &amp;#039;table&amp;#039;})&lt;br /&gt;
	local res = {}&lt;br /&gt;
&lt;br /&gt;
	if type(lhs) == &amp;#039;number&amp;#039; then&lt;br /&gt;
		for i = 1, #rhs do&lt;br /&gt;
			res[i] = fun(lhs, rhs[i])&lt;br /&gt;
		end&lt;br /&gt;
	elseif type(rhs) == &amp;#039;number&amp;#039; then&lt;br /&gt;
		for i = 1, #lhs do&lt;br /&gt;
			res[i] = fun(lhs[i], rhs)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		assert(#lhs == #rhs, string.format(&amp;#039;Elementwise %s failed because arrays have different sizes (left: %d, right: %d)&amp;#039;, opName, #lhs, #rhs))&lt;br /&gt;
		for i = 1, #lhs do&lt;br /&gt;
			res[i] = fun(lhs[i], rhs[i])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return setmetatable(res, getmetatable(lhs) or getmetatable(rhs))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__add(lhs, rhs)&lt;br /&gt;
	return mathTemplate(lhs, rhs, &amp;#039;__add&amp;#039;, &amp;#039;addition&amp;#039;, function(x, y) return x + y end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__sub(lhs, rhs)&lt;br /&gt;
	return mathTemplate(lhs, rhs, &amp;#039;__sub&amp;#039;, &amp;#039;substraction&amp;#039;, function(x, y) return x - y end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__mul(lhs, rhs)&lt;br /&gt;
	return mathTemplate(lhs, rhs, &amp;#039;__mul&amp;#039;, &amp;#039;multiplication&amp;#039;, function(x, y) return x * y end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__div(lhs, rhs)&lt;br /&gt;
	return mathTemplate(lhs, rhs, &amp;#039;__div&amp;#039;, &amp;#039;division&amp;#039;, function(x, y) return x / y end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__pow(lhs, rhs)&lt;br /&gt;
	return mathTemplate(lhs, rhs, &amp;#039;__pow&amp;#039;, &amp;#039;exponentiation&amp;#039;, function(x, y) return x ^ y end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.__eq(lhs, rhs)&lt;br /&gt;
	if #lhs ~= #rhs then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	for i = 1, #lhs do&lt;br /&gt;
		if lhs[i] ~= rhs[i] 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;
---Behaviour depends on the value of `fn`:&lt;br /&gt;
---* `nil` - Checks that the array doesn&amp;#039;t contain any **false** elements.&lt;br /&gt;
---* `fun(elem: any, i?: integer): boolean` - Returns **true** if `fn` returns **true** for every element.&lt;br /&gt;
---* `number` | `table` | `boolean` - Checks that all elements in `arr` are equal to this value.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param fn? any&lt;br /&gt;
---@return boolean&lt;br /&gt;
function Array.all(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.all&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	if fn == nil then fn = function(item) return item end end&lt;br /&gt;
	if type(fn) ~= &amp;#039;function&amp;#039; then&lt;br /&gt;
		local val = fn&lt;br /&gt;
		fn = function(item) return item == val end&lt;br /&gt;
	end&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		---@diagnostic disable-next-line: redundant-parameter&lt;br /&gt;
		if not fn(arr[i], i) then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Behaviour depends on the value of `fn`:&lt;br /&gt;
---* `nil` - Checks that the array contains at least one non **false** element.&lt;br /&gt;
---* `fun(elem: any, i?: integer): boolean` - Returns **true** if `fn` returns **true** for at least one element.&lt;br /&gt;
---* `number` | `table` | `boolean` - Checks that `arr` contains this value.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param fn? any&lt;br /&gt;
---@return boolean&lt;br /&gt;
function Array.any(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.any&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	if fn == nil then fn = function(item) return item end end&lt;br /&gt;
	if type(fn) ~= &amp;#039;function&amp;#039; then&lt;br /&gt;
		local val = fn&lt;br /&gt;
		fn = function(item) return item == val end&lt;br /&gt;
	end&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		---@diagnostic disable-next-line: redundant-parameter&lt;br /&gt;
		if fn(arr[i], i) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Recursively removes all metatables.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@return any[]&lt;br /&gt;
function Array.clean(arr)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.clean&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		if type(arr[i]) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			Array.clean(arr[i])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	setmetatable(arr, nil)&lt;br /&gt;
	return arr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Make a copy of the input table. Preserves metatables.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param deep? boolean # Recursively clone subtables if **true**.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.clone(arr, deep)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.clone&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.clone&amp;#039;, 2, deep, &amp;#039;boolean&amp;#039;, true)&lt;br /&gt;
	local res = {}&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		if deep == true and type(arr[i]) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			res[i] = Array.clone(arr[i], true)&lt;br /&gt;
		else&lt;br /&gt;
			res[i] = arr[i]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(res, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Check if `arr` contains `val`.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param val any&lt;br /&gt;
---@return boolean&lt;br /&gt;
function Array.contains(arr, val)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.contains&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		if arr[i] == val then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Check if `arr` contains any of the values in the table `t`.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param t any[]&lt;br /&gt;
---@return boolean&lt;br /&gt;
function Array.containsAny(arr, t)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.containsAny&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.containsAny&amp;#039;, 2, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local lookupTbl = {}&lt;br /&gt;
	for i = 1, #t do&lt;br /&gt;
		lookupTbl[t[i]] = true&lt;br /&gt;
	end&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		if lookupTbl[arr[i]] then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Check if `arr` contains all values in the table `t`.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param t any[]&lt;br /&gt;
---@return boolean&lt;br /&gt;
function Array.containsAll(arr, t)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.containsAll&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.containsAll&amp;#039;, 2, t, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local lookupTbl = {}&lt;br /&gt;
	local l = #t&lt;br /&gt;
	local trueCount = 0&lt;br /&gt;
	for i = 1, l do&lt;br /&gt;
		lookupTbl[t[i]] = false&lt;br /&gt;
	end&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		if lookupTbl[arr[i]] == false then&lt;br /&gt;
			lookupTbl[arr[i]] = true&lt;br /&gt;
			trueCount = trueCount + 1&lt;br /&gt;
		end&lt;br /&gt;
		if trueCount == l then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Convolute two number arrays.&lt;br /&gt;
---@generic T: number[]&lt;br /&gt;
---@param x T&lt;br /&gt;
---@param y T&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.convolve(x, y)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.convolve&amp;#039;, 1, x, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.convolve&amp;#039;, 2, y, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local z = {}&lt;br /&gt;
    local xLen, yLen = #x, #y&lt;br /&gt;
    for j = 1, (xLen + yLen - 1) do&lt;br /&gt;
        local sum = 0&lt;br /&gt;
        for k = math.max(1, j - yLen + 1), math.min(xLen, j) do&lt;br /&gt;
            sum = sum + x[k] * y[j-k+1]&lt;br /&gt;
        end&lt;br /&gt;
        z[j] = sum&lt;br /&gt;
    end&lt;br /&gt;
    return setmetatable(z, getmetatable(x) or getmetatable(y))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Remove **nil** values from `arr` while preserving order.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.condenseSparse(arr)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.condenseSparse&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local keys = {}&lt;br /&gt;
	local res = {}&lt;br /&gt;
	local l = 0&lt;br /&gt;
	for k in pairs(arr) do&lt;br /&gt;
		l = l + 1&lt;br /&gt;
		keys[l] = k&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(keys)&lt;br /&gt;
	for i =  1, l do&lt;br /&gt;
		res[i] = arr[keys[i]]&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(res, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Behaviour depends on value of `val`:&lt;br /&gt;
---* `nil` - Counts the number of non **false** elements.&lt;br /&gt;
---* `fun(elem: any): boolean` - Count the number of times the function returned **true**.&lt;br /&gt;
---* `boolean` | `number` | `table` - Counts the number of times this value occurs in `arr`.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param val? any&lt;br /&gt;
---@return integer&lt;br /&gt;
function Array.count(arr, val)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.count&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	if val == nil then val = function(item) return item end end&lt;br /&gt;
	if type(val) ~= &amp;#039;function&amp;#039; then&lt;br /&gt;
		local _val = val&lt;br /&gt;
		val = function(item) return item == _val end&lt;br /&gt;
	end&lt;br /&gt;
	local count = 0&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		if val(arr[i]) then&lt;br /&gt;
			count = count + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Differentiate the array&lt;br /&gt;
---@generic T: number[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param order number? # Oder of the differentiation. Default is 1.&lt;br /&gt;
---@return T # Length is `#arr - order`&lt;br /&gt;
function Array.diff(arr, order)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.diff&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.diff&amp;#039;, 2, order, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	local res = {}&lt;br /&gt;
	for i = 1, #arr - 1 do&lt;br /&gt;
		res[i] = arr[i+1] - arr[i]&lt;br /&gt;
	end&lt;br /&gt;
	if order and order &amp;gt; 1 then&lt;br /&gt;
		return Array.diff(res, order - 1)&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(res, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Loops over `arr` and passes each element as the first argument to `fn`. This function returns nothing.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param fn fun(elem: any, i?: integer)&lt;br /&gt;
function Array.each(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.each&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.each&amp;#039;, 2, fn, &amp;#039;function&amp;#039;)&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		fn(arr[i], i)&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Makes a copy of `arr` with only elements for which `fn` returned **true**.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param fn fun(elem: any, i?: integer): boolean&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.filter(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.filter&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.filter&amp;#039;, 2, fn, &amp;#039;function&amp;#039;)&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		if fn(arr[i], i) then&lt;br /&gt;
			len = len + 1&lt;br /&gt;
			r[len] = arr[i]&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Find the first elements for which `fn` returns **true**.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param fn any # A value to look for or a function of the form `fun(elem: any, i?: integer): boolean`.&lt;br /&gt;
---@param default? any # Value to return if no element passes the test.&lt;br /&gt;
---@return any? elem # The first element that passed the test.&lt;br /&gt;
---@return integer? i # The index of the item that passed the test.&lt;br /&gt;
function Array.find(arr, fn, default)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.find&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.find_index&amp;#039;, 2, fn, {&amp;#039;function&amp;#039;, &amp;#039;table&amp;#039;, &amp;#039;number&amp;#039;, &amp;#039;boolean&amp;#039;})&lt;br /&gt;
	if type(fn) ~= &amp;#039;function&amp;#039; then&lt;br /&gt;
		local _val = fn&lt;br /&gt;
		fn = function(item) return item == _val end&lt;br /&gt;
	end&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		---@diagnostic disable-next-line: redundant-parameter&lt;br /&gt;
		if fn(arr[i], i) then&lt;br /&gt;
			return arr[i], i&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return default, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Find the index of `val`.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param val any # A value to look for or a function of the form `fun(elem: any, i?: integer): boolean`.&lt;br /&gt;
---@param default? any # Value to return if no element passes the test.&lt;br /&gt;
---@return integer?&lt;br /&gt;
function Array.find_index(arr, val, default)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.find_index&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.find_index&amp;#039;, 2, val, {&amp;#039;function&amp;#039;, &amp;#039;table&amp;#039;, &amp;#039;number&amp;#039;, &amp;#039;boolean&amp;#039;})&lt;br /&gt;
	if type(val) ~= &amp;#039;function&amp;#039; then&lt;br /&gt;
		local _val = val&lt;br /&gt;
		val = function(item) return item == _val end&lt;br /&gt;
	end&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		---@diagnostic disable-next-line: redundant-parameter&lt;br /&gt;
		if val(arr[i], i) then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return default&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Extracts a subset of `arr`.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param indexes integer|integer[] # Indexes of the elements.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.get(arr, indexes)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.set&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.set&amp;#039;, 2, indexes, {&amp;#039;table&amp;#039;, &amp;#039;number&amp;#039;})&lt;br /&gt;
	if type(indexes) == &amp;#039;number&amp;#039; then&lt;br /&gt;
		indexes = {indexes}&lt;br /&gt;
	end&lt;br /&gt;
	local res = {}&lt;br /&gt;
	for i = 1, #indexes do&lt;br /&gt;
		 res[i] = arr[indexes[i]]&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(res, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Integrates the array. Effectively does $\left\{\sum^{n}_{start}{arr[n]} \,\Bigg|\, n \in [start, stop]\right\}$.&lt;br /&gt;
---@generic T: number[]&lt;br /&gt;
---@param arr T # number[]&lt;br /&gt;
---@param start? integer # Index where to start the summation. Defaults to 1.&lt;br /&gt;
---@param stop? integer # Index where to stop the summation. Defaults to #arr.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.int(arr, start, stop)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.int&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.int&amp;#039;, 2, start, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.int&amp;#039;, 3, stop, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	local res = {}&lt;br /&gt;
	start = start or 1&lt;br /&gt;
	stop = stop or #arr&lt;br /&gt;
	res[1] = arr[start]&lt;br /&gt;
	for i = 1, stop - start do&lt;br /&gt;
		res[i+1] = res[i] + arr[start + i]&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(res, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Returns an array with elements that are present in both tables.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr1 T&lt;br /&gt;
---@param arr2 T&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.intersect(arr1, arr2)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.intersect&amp;#039;, 1, arr1, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.intersect&amp;#039;, 2, arr2, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local arr2Elements = {}&lt;br /&gt;
	local res = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	Array.each(arr2, function(item) arr2Elements[item] = true end)&lt;br /&gt;
	Array.each(arr1, function(item)&lt;br /&gt;
		if arr2Elements[item] then&lt;br /&gt;
			len = len + 1&lt;br /&gt;
			res[len] = item&lt;br /&gt;
		end&lt;br /&gt;
	end)&lt;br /&gt;
	return setmetatable(res, getmetatable(arr1) or getmetatable(arr2))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Checks if the two inputs have at least one element in common.&lt;br /&gt;
---@param arr1 any[]&lt;br /&gt;
---@param arr2 any[]&lt;br /&gt;
---@return boolean&lt;br /&gt;
function Array.intersects(arr1, arr2)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.intersects&amp;#039;, 1, arr1, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.intersects&amp;#039;, 2, arr2, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local small = {}&lt;br /&gt;
	local large&lt;br /&gt;
	if #arr1 &amp;lt;= #arr2 then&lt;br /&gt;
		Array.each(arr1, function(item) small[item] = true end)&lt;br /&gt;
		large = arr2&lt;br /&gt;
	else&lt;br /&gt;
		Array.each(arr2, function(item) small[item] = true end)&lt;br /&gt;
		large = arr1&lt;br /&gt;
	end&lt;br /&gt;
	return Array.any(large, function(item) return small[item] end)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Inserts values into `arr`.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param val any # If `val` is an array and `unpackVal` is **true** then the individual elements of `val` are inserted.&lt;br /&gt;
---@param index? integer # Location to start the insertion. Default is at the end of `arr`.&lt;br /&gt;
---@param unpackVal? boolean # Default is **false**.&lt;br /&gt;
---@return T&lt;br /&gt;
---@overload fun(arr: T, val: any, unpackVal: boolean): T&lt;br /&gt;
function Array.insert(arr, val, index, unpackVal)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.insert&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.insert&amp;#039;, 3, index, {&amp;#039;number&amp;#039;, &amp;#039;boolean&amp;#039;, &amp;#039;nil&amp;#039;})&lt;br /&gt;
	checkType(&amp;#039;Module:Array.insert&amp;#039;, 4, unpackVal, &amp;#039;boolean&amp;#039;, true)&lt;br /&gt;
	if type(index) == &amp;#039;boolean&amp;#039;  then&lt;br /&gt;
		unpackVal, index = index, nil&lt;br /&gt;
	end&lt;br /&gt;
	local len = #arr&lt;br /&gt;
	index = index or (len + 1)&lt;br /&gt;
	local mt = getmetatable(arr)&lt;br /&gt;
	setmetatable(arr, nil)&lt;br /&gt;
&lt;br /&gt;
	if type(val) == &amp;#039;table&amp;#039; and unpackVal then&lt;br /&gt;
		local len2 = #val&lt;br /&gt;
		for i = 0, len - index do&lt;br /&gt;
			arr[len + len2 - i] = arr[len - i]&lt;br /&gt;
		end&lt;br /&gt;
		for i = 0, len2 - 1 do&lt;br /&gt;
			arr[index + i] = val[i + 1]&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(arr, index, val)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return setmetatable(arr, mt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Returns the last element of `arr`.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param offset? integer&lt;br /&gt;
---@return any&lt;br /&gt;
function Array.last(arr, offset)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.last&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.last&amp;#039;, 2, offset, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	return arr[#arr + offset]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Returns a new table were each element of `arr` is modified by `fn`.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param fn fun(elem: any, i?: integer): any # First argument is the current element, the second argument is the index of the current element.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.map(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.map&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.map&amp;#039;, 2, fn, &amp;#039;function&amp;#039;)&lt;br /&gt;
	local len = 0&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		local tmp = fn(arr[i], i)&lt;br /&gt;
		if tmp ~= nil then&lt;br /&gt;
			len = len + 1&lt;br /&gt;
			r[len] = tmp&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Find the element for which `fn` returned the largest value.&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param fn fun(elem: any): any # The returned value needs to be comparable using the `&amp;lt;` operator.&lt;br /&gt;
---@return any elem # The element with the largest `fn` value.&lt;br /&gt;
---@return integer i # The index of this element.&lt;br /&gt;
function Array.max_by(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.max_by&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.max_by&amp;#039;, 2, fn, &amp;#039;function&amp;#039;)&lt;br /&gt;
	return unpack(Array.reduce(arr, function(new, old, i)&lt;br /&gt;
		local y = fn(new)&lt;br /&gt;
		return y &amp;gt; old[2] and {new, y, i} or old&lt;br /&gt;
	end, {nil, -math.huge}))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Find the largest value in the array.&lt;br /&gt;
---@param arr any[] # The values need to be comparable using the `&amp;lt;` operator.&lt;br /&gt;
---@return any elem&lt;br /&gt;
---@return integer i # The index of the largest value.&lt;br /&gt;
function Array.max(arr)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.max&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local val, _, i = Array.max_by(arr, function(x) return x end)&lt;br /&gt;
	return val, i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Find the smallest value in the array.&lt;br /&gt;
---@param arr any[] # The values need to be comparable using the `&amp;lt;` operator.&lt;br /&gt;
---@return any elem&lt;br /&gt;
---@return integer i # The index of the smallest value.&lt;br /&gt;
function Array.min(arr)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.min&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local val, _, i = Array.max_by(arr, function(x) return -x end)&lt;br /&gt;
	return val, i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Turn the input table into an Array. This makes it possible to use the colon `:` operator to access the Array methods.&lt;br /&gt;
---&lt;br /&gt;
---It also enables the use of math operators with the array.&lt;br /&gt;
---```&lt;br /&gt;
---local x = arr.new{ 1, 2, 3 }&lt;br /&gt;
---local y = arr{ 4, 5, 6 } -- Alternative notation&lt;br /&gt;
---&lt;br /&gt;
---print( -x ) --&amp;gt; { -1, -2, -3 }&lt;br /&gt;
---print( x + 2 ) --&amp;gt; { 3, 4, 5 }&lt;br /&gt;
---print( x - 2 ) --&amp;gt; { -1, 0, 1 }&lt;br /&gt;
---print( x * 2 ) --&amp;gt; { 2, 4, 6 }&lt;br /&gt;
---print( x / 2 ) --&amp;gt; { 0.5, 1, 1.5 }&lt;br /&gt;
---print( x ^ 2 ) --&amp;gt; { 1, 4, 9 }&lt;br /&gt;
---&lt;br /&gt;
---print( x + y ) --&amp;gt; { 5, 7, 9 }&lt;br /&gt;
---print( x .. y ) --&amp;gt; { 1, 2, 3, 4, 5, 6 }&lt;br /&gt;
---print( (x .. y):reject{3, 4, 5} ) --&amp;gt; { 1, 2, 6 }&lt;br /&gt;
---print( x:sum() ) --&amp;gt; 6&lt;br /&gt;
---&lt;br /&gt;
---print( x:update( {1, 3}, y:get{2, 3} * 2 ) ) --&amp;gt; { 10, 2, 12 }&lt;br /&gt;
---```&lt;br /&gt;
---@param arr? any[]&lt;br /&gt;
---@return Array&lt;br /&gt;
function Array.new(arr)&lt;br /&gt;
	local obj = arr or {}&lt;br /&gt;
	for _, v in pairs(obj) do&lt;br /&gt;
		if type(v) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			Array.new(v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if getmetatable(obj) == nil then&lt;br /&gt;
		setmetatable(obj, Array)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return obj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Creates an object that returns a value that is `step` higher than the previous value each time it gets called.&lt;br /&gt;
---&lt;br /&gt;
---The stored value can be read without incrementing by reading the `val` field.&lt;br /&gt;
---&lt;br /&gt;
---A new stored value can be set through the `val` field.&lt;br /&gt;
---&lt;br /&gt;
---A new step size can be set through the `step` field.&lt;br /&gt;
---```&lt;br /&gt;
---local inc = arr.newIncrementor(10, 5)&lt;br /&gt;
---print( inc() ) --&amp;gt; 10&lt;br /&gt;
---print( inc() ) --&amp;gt; 15&lt;br /&gt;
---print( inc.val ) --&amp;gt; 15&lt;br /&gt;
---inc.val = 100&lt;br /&gt;
---inc.step = 20&lt;br /&gt;
---print( inc.val ) --&amp;gt; 100&lt;br /&gt;
---print( inc() ) --&amp;gt; 120&lt;br /&gt;
---```&lt;br /&gt;
---@param start? number # Default is 1.&lt;br /&gt;
---@param step? number # Default is 1.&lt;br /&gt;
---@return Incrementor&lt;br /&gt;
function Array.newIncrementor(start, step)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.newIncrementor&amp;#039;, 1, start, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.newIncrementor&amp;#039;, 2, step, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	step = step or 1&lt;br /&gt;
	local n = (start or 1) - step&lt;br /&gt;
	---@class Incrementor&lt;br /&gt;
	local obj = {}&lt;br /&gt;
	return setmetatable(obj, {&lt;br /&gt;
		__call = function() n = n + step return n end,&lt;br /&gt;
		__tostring = function() return n end,&lt;br /&gt;
		__index = function() return n end,&lt;br /&gt;
		__newindex = function(self, k, v)&lt;br /&gt;
			if k == &amp;#039;step&amp;#039; and type(v) == &amp;#039;number&amp;#039; then&lt;br /&gt;
				step = v&lt;br /&gt;
			elseif type(v) == &amp;#039;number&amp;#039; then&lt;br /&gt;
				n = v&lt;br /&gt;
			end&lt;br /&gt;
		end,&lt;br /&gt;
		__concat = function(x, y) return tostring(x) .. tostring(y) end&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Returns a range of numbers.&lt;br /&gt;
---@param start number # Start value inclusive.&lt;br /&gt;
---@param stop number # Stop value inclusive for integers, exclusive for floats.&lt;br /&gt;
---@param step? number # Default is 1.&lt;br /&gt;
---@return Array&lt;br /&gt;
---@overload fun(stop: number): Array&lt;br /&gt;
function Array.range(start, stop, step)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.range&amp;#039;, 1, start, &amp;#039;number&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.range&amp;#039;, 2, stop, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.range&amp;#039;, 3, step, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	local arr = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	if not stop then&lt;br /&gt;
		stop = start&lt;br /&gt;
		start = 1&lt;br /&gt;
	end&lt;br /&gt;
	for i = start, stop, step or 1 do&lt;br /&gt;
		len = len + 1&lt;br /&gt;
		arr[len] = i&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(arr, Array)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Condenses the array into a single value.&lt;br /&gt;
---&lt;br /&gt;
---For each element `fn` is called with the current element, the current accumulator, and the current element index. The returned value of `fn` becomes the accumulator for the next element.&lt;br /&gt;
---&lt;br /&gt;
---If no `accumulator` value is given at the start then the first element off `arr` becomes the accumulator and the iteration starts from the second element.&lt;br /&gt;
---```&lt;br /&gt;
---local t = { 1, 2, 3, 4 }&lt;br /&gt;
---local sum = arr.reduce( t, function(elem, acc) return acc + elem end ) -- sum == 10&lt;br /&gt;
---```&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param fn fun(elem: any, acc: any, i?: integer): any # The result of this function becomes the `acc` for the next element.&lt;br /&gt;
---@param accumulator? any&lt;br /&gt;
---@return any # This is the last accumulator value.&lt;br /&gt;
function Array.reduce(arr, fn, accumulator)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.reduce&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.reduce&amp;#039;, 2, fn, &amp;#039;function&amp;#039;)&lt;br /&gt;
	local acc = accumulator&lt;br /&gt;
	local i = 1&lt;br /&gt;
	if acc == nil then&lt;br /&gt;
		acc = arr[1]&lt;br /&gt;
		i = 2&lt;br /&gt;
	end&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		acc = fn(arr[i], acc, i)&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return acc&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Make a copy off `arr` with certain values removed.&lt;br /&gt;
---&lt;br /&gt;
---Behaviour for different values of `val`:&lt;br /&gt;
---* `boolean` | `number` - Remove values equal to this.&lt;br /&gt;
---* `table` - Remove all values in this table.&lt;br /&gt;
---* `fun(elem: any, i?: integer): boolean` - Remove elements for which the functions returns **true**.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param val table|function|number|boolean&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.reject(arr, val)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.reject&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.reject&amp;#039;, 2, val, {&amp;#039;function&amp;#039;, &amp;#039;table&amp;#039;, &amp;#039;number&amp;#039;, &amp;#039;boolean&amp;#039;})&lt;br /&gt;
	if type(val) ~= &amp;#039;function&amp;#039; and type(val) ~= &amp;#039;table&amp;#039; then&lt;br /&gt;
		val = {val}&lt;br /&gt;
	end&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	if type(val) == &amp;#039;function&amp;#039; then&lt;br /&gt;
		local i = 1&lt;br /&gt;
		while arr[i] ~= nil do&lt;br /&gt;
			if not val(arr[i], i) then&lt;br /&gt;
				len = len + 1&lt;br /&gt;
				r[len] = arr[i]&lt;br /&gt;
			end&lt;br /&gt;
			i = i + 1&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		local rejectMap = {}&lt;br /&gt;
		Array.each(val --[[@as any[] ]], function(item) rejectMap[item] = true end)&lt;br /&gt;
		local i = 1&lt;br /&gt;
		while arr[i] ~= nil do&lt;br /&gt;
			if not rejectMap[arr[i]] then&lt;br /&gt;
				len = len + 1&lt;br /&gt;
				r[len] = arr[i]&lt;br /&gt;
			end&lt;br /&gt;
			i = i + 1&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Returns an Array with `val` repeated `n` times.&lt;br /&gt;
---@param val any&lt;br /&gt;
---@param n integer&lt;br /&gt;
---@return Array&lt;br /&gt;
function Array.rep(val, n)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.rep&amp;#039;, 2, n, &amp;#039;number&amp;#039;)&lt;br /&gt;
	local r = {}&lt;br /&gt;
	for i = 1, n do&lt;br /&gt;
		r[i] = val&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, Array)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Condenses the array into a single value while saving every accumulator value.&lt;br /&gt;
---&lt;br /&gt;
---For each element `fn` is called with the current element, the current accumulator, and the current element index. The returned value of `fn` becomes the accumulator for the next element.&lt;br /&gt;
---&lt;br /&gt;
---If no `accumulator` value is given at the start then the first element off `arr` becomes the accumulator and the iteration starts from the second element.&lt;br /&gt;
---```&lt;br /&gt;
---local t = { 1, 2, 3, 4 }&lt;br /&gt;
---local x = arr.scan( t, function(elem, acc) return acc + elem end ) -- x = { 1, 3, 6, 10 }&lt;br /&gt;
---```&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param fn fun(elem: any, acc: any, i?: integer): any # Returned value becomes the accumulator for the next element.&lt;br /&gt;
---@param accumulator? any&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.scan(arr, fn, accumulator)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.scan&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.scan&amp;#039;, 2, fn, &amp;#039;function&amp;#039;)&lt;br /&gt;
	local acc = accumulator&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		if i == 1 and not accumulator then&lt;br /&gt;
			acc = arr[i]&lt;br /&gt;
		else&lt;br /&gt;
			acc = fn(arr[i], acc, i)&lt;br /&gt;
		end&lt;br /&gt;
		r[i] = acc&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Update a range of index with a range of values.&lt;br /&gt;
---&lt;br /&gt;
---If if only one value is given but multiple indexes than that value is set for all those indexes.&lt;br /&gt;
---&lt;br /&gt;
---If `values` is a table then it must of the same length as `indexes`.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param indexes integer|integer[]&lt;br /&gt;
---@param values any|any[]&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.set(arr, indexes, values)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.set&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkTypeMulti(&amp;#039;Module:Array.set&amp;#039;, 2, indexes, {&amp;#039;table&amp;#039;, &amp;#039;number&amp;#039;})&lt;br /&gt;
	local mt = getmetatable(arr)&lt;br /&gt;
	setmetatable(arr, nil)&lt;br /&gt;
	if type(indexes) == &amp;#039;number&amp;#039; then&lt;br /&gt;
		indexes = {indexes}&lt;br /&gt;
	end&lt;br /&gt;
	if type(values) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		assert(#indexes == #values, string.format(&amp;quot;Module:Array.set: &amp;#039;indexes&amp;#039; and &amp;#039;values&amp;#039; arrays are not equal length (#indexes = %d, #values = %d)&amp;quot;, #indexes, #values))&lt;br /&gt;
		for i = 1, #indexes do&lt;br /&gt;
			arr[indexes[i]] = values[i]&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for i = 1, #indexes do&lt;br /&gt;
			arr[indexes[i]] = values&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(arr, mt)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Extract a subtable from `arr`.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param start integer # Start index. Use negative values to count form the end of the array.&lt;br /&gt;
---@param stop integer # Stop index. Use negative values to count form the end of the array.&lt;br /&gt;
---@return T&lt;br /&gt;
---@overload fun(arr: T, stop: integer): T&lt;br /&gt;
function Array.slice(arr, start, stop)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.slice&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.slice&amp;#039;, 2, start, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.slice&amp;#039;, 3, stop, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	start = start or #arr&lt;br /&gt;
	if start &amp;lt; 0 then&lt;br /&gt;
		start = #arr + start&lt;br /&gt;
	end&lt;br /&gt;
	if stop == nil then&lt;br /&gt;
		stop = start&lt;br /&gt;
		start = 1&lt;br /&gt;
	end&lt;br /&gt;
	if stop &amp;lt; 0 then&lt;br /&gt;
		stop = #arr + stop&lt;br /&gt;
	end&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	for i = start, stop do&lt;br /&gt;
		len = len + 1&lt;br /&gt;
		r[len] = arr[i]&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Split `arr` into two arrays.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param index integer # Index to split on.&lt;br /&gt;
---@return T x # [1, index]&lt;br /&gt;
---@return T y # [index + 1, #arr]&lt;br /&gt;
function Array.split(arr, index)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.split&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.split&amp;#039;, 2, index, &amp;#039;number&amp;#039;)&lt;br /&gt;
	local x = {}&lt;br /&gt;
	local y = {}&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		table.insert(i &amp;lt;= index and x or y, arr[i])&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(x, getmetatable(arr)), setmetatable(y, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Returns the sum of all elements of `arr`.&lt;br /&gt;
---@param arr number[]&lt;br /&gt;
---@return number&lt;br /&gt;
function Array.sum(arr)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.sum&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	local res = 0&lt;br /&gt;
	for i = 1, #arr do&lt;br /&gt;
		res = res + arr[i]&lt;br /&gt;
	end&lt;br /&gt;
	return res&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Extract a subtable from `arr`.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param count integer # Length of the subtable.&lt;br /&gt;
---@param start? integer # Start index. Default is 1.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.take(arr, count, start)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take&amp;#039;, 2, count, &amp;#039;number&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take&amp;#039;, 3, start, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	local x = {}&lt;br /&gt;
	start = start or 1&lt;br /&gt;
	for i = start, math.min(#arr, count + start - 1) do&lt;br /&gt;
		table.insert(x, arr[i])&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(x, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Extract a subtable from `arr`.&lt;br /&gt;
---```&lt;br /&gt;
---local t = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }&lt;br /&gt;
---local x = arr.take_every( t, 2 )       --&amp;gt; x = { 1, 3, 5, 7, 9 }&lt;br /&gt;
---local x = arr.take_every( t, 2, 3 )    --&amp;gt; x = { 1, 3, 5 }&lt;br /&gt;
---local x = arr.take_every( t, 2, 3, 2 ) --&amp;gt; x = { 2, 4, 6 }&lt;br /&gt;
--- ```&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param n integer # Step size.&lt;br /&gt;
---@param start? integer # Start index.&lt;br /&gt;
---@param count? integer # Max amount of elements to get.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.take_every(arr, n, start, count)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take_every&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take_every&amp;#039;, 2, n, &amp;#039;number&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take_every&amp;#039;, 3, start, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.take_every&amp;#039;, 4, count, &amp;#039;number&amp;#039;, true)&lt;br /&gt;
	count = count or #arr&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	local i = start or 1&lt;br /&gt;
	while arr[i] ~= nil and len &amp;lt; count do&lt;br /&gt;
		len = len + 1&lt;br /&gt;
		r[len] = arr[i]&lt;br /&gt;
		i = i + n&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Return a new table with all duplicates removed.&lt;br /&gt;
---@generic T: any[]&lt;br /&gt;
---@param arr T&lt;br /&gt;
---@param fn? fun(elem: any): any # Function to generate an id for each element. The result will then contain elements that generated unique ids.&lt;br /&gt;
---@return T&lt;br /&gt;
function Array.unique(arr, fn)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.unique&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.unique&amp;#039;, 2, fn, &amp;#039;function&amp;#039;, true)&lt;br /&gt;
	fn = fn or function(item) return item end&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local len = 0&lt;br /&gt;
	local hash = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	while arr[i] ~= nil do&lt;br /&gt;
		local id = fn(arr[i])&lt;br /&gt;
		if not hash[id] then&lt;br /&gt;
			len = len + 1&lt;br /&gt;
			r[len] = arr[i]&lt;br /&gt;
			hash[id] = true&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, getmetatable(arr))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Combine elements with the same index from multiple arrays.&lt;br /&gt;
---```&lt;br /&gt;
---local x = {1, 2, 3}&lt;br /&gt;
---local y = {4, 5, 6, 7}&lt;br /&gt;
---local z = arr.zip( x, y ) --&amp;gt; z = { { 1, 4 }, { 2, 5 }, { 3, 6 }, { 7 } }&lt;br /&gt;
---```&lt;br /&gt;
---@param ... any[]&lt;br /&gt;
---@return Array&lt;br /&gt;
function Array.zip(...)&lt;br /&gt;
	local arrs = { ... }&lt;br /&gt;
	checkType(&amp;#039;Module:Array.zip&amp;#039;, 1, arrs[1], &amp;#039;table&amp;#039;)&lt;br /&gt;
	local r = {}&lt;br /&gt;
	local _, longest = Array.max_by(arrs, function(arr) return #arr end)&lt;br /&gt;
	for i = 1, longest do&lt;br /&gt;
		local q = {}&lt;br /&gt;
		for j = 1, #arrs do&lt;br /&gt;
			table.insert(q, arrs[j][i])&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(r, setmetatable(q, Array))&lt;br /&gt;
	end&lt;br /&gt;
	return setmetatable(r, Array)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Range indexing has a performance impact so this is placed in a separate subclass&lt;br /&gt;
Array.RI_mt = {}&lt;br /&gt;
for k, v in pairs(Array) do&lt;br /&gt;
	Array.RI_mt[k] = v&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.RI_mt.__index(t, k)&lt;br /&gt;
	if type(k) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		local res = {}&lt;br /&gt;
		for i = 1, #k do&lt;br /&gt;
			res[i] = t[k[i]]&lt;br /&gt;
		end&lt;br /&gt;
		return setmetatable(res, Array)&lt;br /&gt;
	else&lt;br /&gt;
		return Array[k]&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Array.RI_mt.__newindex(t, k, v)&lt;br /&gt;
	if type(k) == &amp;#039;table&amp;#039; then&lt;br /&gt;
		if type(v) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			for i = 1, #k do&lt;br /&gt;
				t[k[i]] = v[i]&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			for i = 1, #k do&lt;br /&gt;
				t[k[i]] = v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		rawset(t, k, v)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Enable range indexing on the input array.&lt;br /&gt;
---&lt;br /&gt;
---This has a performance impact on reads and writes to the table.&lt;br /&gt;
---```&lt;br /&gt;
---local t = arr{10, 11, 12, 13, 14, 15}:ri()&lt;br /&gt;
---print( t[{2, 3}] ) --&amp;gt; { 11, 12 }&lt;br /&gt;
---```&lt;br /&gt;
---@param arr any[]&lt;br /&gt;
---@param recursive? boolean # Default is false.&lt;br /&gt;
---@return Array&lt;br /&gt;
function Array.ri(arr, recursive)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.ri&amp;#039;, 1, arr, &amp;#039;table&amp;#039;)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.ri&amp;#039;, 2, recursive, &amp;#039;boolean&amp;#039;, true)&lt;br /&gt;
	arr = arr or {}&lt;br /&gt;
	if recursive then&lt;br /&gt;
		for _, v in pairs(arr) do&lt;br /&gt;
			if type(v) == &amp;#039;table&amp;#039; then&lt;br /&gt;
				Array.ri(v, true)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if getmetatable(arr) == nil or getmetatable(arr) == Array then&lt;br /&gt;
		setmetatable(arr, Array.RI_mt)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return arr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Globally enable range indexing on all Array objects by default.&lt;br /&gt;
---@param set boolean&lt;br /&gt;
function Array.allwaysAllowRangeIndexing(set)&lt;br /&gt;
	checkType(&amp;#039;Module:Array.allwaysAllowRangeIndexing&amp;#039;, 1, set, &amp;#039;boolean&amp;#039;)&lt;br /&gt;
	if set then&lt;br /&gt;
		Array.__index = Array.RI_mt.__index&lt;br /&gt;
		Array.__newindex = Array.RI_mt.__newindex&lt;br /&gt;
	else&lt;br /&gt;
		Array.__index = Array&lt;br /&gt;
		Array.__newindex = nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return Array&lt;/div&gt;</summary>
		<author><name>Zeroclanzhang</name></author>
	</entry>
</feed>