Module:Array: Difference between revisions

From Ato Wiki
starcitizen>Alistair3149
(Created page with "-- <nowiki> awawa local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti local arr = {} setmetatable(arr, { __call = function (_, array) return arr.new(array) end }) function arr.__index(t, k) if type(k) == 'table' then local res = arr.new() for i = 1, #t do res[i] = t[k[i]] end return res else return arr[k] end end function arr.__tostring(array) local dumpObject = requi...")
 
starcitizen>Alistair3149
(Sync with upstream)
Line 1: Line 1:
-- <nowiki> awawa
-- Imported from: https://runescape.wiki/w/Module:Array
 
-- <nowiki>
local libraryUtil = require('libraryUtil')
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkType = libraryUtil.checkType
Line 6: Line 8:


setmetatable(arr, {
setmetatable(arr, {
__call = function (_, array)
    __call = function (_, array)
return arr.new(array)
        return arr.new(array)
end
    end
})
})


function arr.__index(t, k)
function arr.__index(t, k)
if type(k) == 'table' then
    if type(k) == 'table' then
local res = arr.new()
        local res = arr.new()
for i = 1, #t do
        for i = 1, #t do
res[i] = t[k[i]]
            res[i] = t[k[i]]
end
        end
return res
        return res
else
    else
return arr[k]
        return arr[k]
end
    end
end
end


function arr.__tostring(array)
function arr.__tostring(array)
local dumpObject = require('Module:Logger').dumpObject
    local dumpObject = require('Module:Logger').dumpObject
setmetatable(array, nil)
    setmetatable(array, nil)
local str = dumpObject(array, {clean=true, collapseLimit=100})
    local str = dumpObject(array, {clean=true, collapseLimit=100})
setmetatable(array, arr)
    setmetatable(array, arr)
return str
    return str
end
end


function arr.__concat(lhs, rhs)
function arr.__concat(lhs, rhs)
if type(lhs) == 'table' and type(rhs) == 'table' then
    if type(lhs) == 'table' and type(rhs) == 'table' then
local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs))
        local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs))
for i = 1, #lhs do
        for i = 1, #lhs do
res[i] = lhs[i]
            res[i] = lhs[i]
end
        end
local l = #lhs
        local l = #lhs
for i = 1, #rhs do
        for i = 1, #rhs do
res[i + l] = rhs[i]
            res[i + l] = rhs[i]
end
        end
return res
        return res
else
    else
return tostring(lhs) .. tostring(rhs)
        return tostring(lhs) .. tostring(rhs)
end
    end
end
end


function arr.__unm(array)
function arr.__unm(array)
return arr.map(array, function(x) return -x end)
    return arr.map(array, function(x) return -x end)
end
end


local function mathTemplate(lhs, rhs, funName, fun)
local function mathTemplate(lhs, rhs, funName, fun)
checkTypeMulti('Module:Array.' .. funName, 1, lhs, {'number', 'table'})
    checkTypeMulti('Module:Array.' .. funName, 1, lhs, {'number', 'table'})
checkTypeMulti('Module:Array.' .. funName, 2, rhs, {'number', 'table'})
    checkTypeMulti('Module:Array.' .. funName, 2, rhs, {'number', 'table'})
local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs))
    local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs))


if type(lhs) == 'number' then
    if type(lhs) == 'number' then
for i = 1, #rhs do
        for i = 1, #rhs do
res[i] = fun(lhs, rhs[i])
            res[i] = fun(lhs, rhs[i])
end
        end
elseif type(rhs) == 'number' then
    elseif type(rhs) == 'number' then
for i = 1, #lhs do
        for i = 1, #lhs do
res[i] = fun(lhs[i], rhs)
            res[i] = fun(lhs[i], rhs)
end
        end
else
    else
assert(#lhs == #rhs, string.format('Tables are not equal length (lhs=%d, rhs=%d)', #lhs, #rhs))
        assert(#lhs == #rhs, string.format('Tables are not equal length (lhs=%d, rhs=%d)', #lhs, #rhs))
for i = 1, #lhs do
        for i = 1, #lhs do
res[i] = fun(lhs[i], rhs[i])
            res[i] = fun(lhs[i], rhs[i])
end
        end
end
    end


return res
    return res
end
end


function arr.__add(lhs, rhs)
function arr.__add(lhs, rhs)
return mathTemplate(lhs, rhs, '__add', function(x, y) return x + y end)
    return mathTemplate(lhs, rhs, '__add', function(x, y) return x + y end)
end
end


function arr.__sub(lhs, rhs)
function arr.__sub(lhs, rhs)
return mathTemplate(lhs, rhs, '__sub', function(x, y) return x - y end)
    return mathTemplate(lhs, rhs, '__sub', function(x, y) return x - y end)
end
end


function arr.__mul(lhs, rhs)
function arr.__mul(lhs, rhs)
return mathTemplate(lhs, rhs, '__mul', function(x, y) return x * y end)
    return mathTemplate(lhs, rhs, '__mul', function(x, y) return x * y end)
end
end


function arr.__div(lhs, rhs)
function arr.__div(lhs, rhs)
return mathTemplate(lhs, rhs, '__div', function(x, y) return x / y end)
    return mathTemplate(lhs, rhs, '__div', function(x, y) return x / y end)
end
end


function arr.__pow(lhs, rhs)
function arr.__pow(lhs, rhs)
return mathTemplate(lhs, rhs, '__pow', function(x, y) return x ^ y end)
    return mathTemplate(lhs, rhs, '__pow', function(x, y) return x ^ y end)
end
end


function arr.__lt(lhs, rhs)
function arr.__lt(lhs, rhs)
for i = 1, math.min(#lhs, #rhs) do
    for i = 1, math.min(#lhs, #rhs) do
if lhs[i] >= rhs[i] then
        if lhs[i] >= rhs[i] then
return false
            return false
end
        end
end
    end
return true
    return true
end
end


function arr.__le(lhs, rhs)
function arr.__le(lhs, rhs)
for i = 1, math.min(#lhs, #rhs) do
    for i = 1, math.min(#lhs, #rhs) do
if lhs[i] > rhs[i] then
        if lhs[i] > rhs[i] then
return false
            return false
end
        end
end
    end
return true
    return true
end
end


function arr.__eq(lhs, rhs)
function arr.__eq(lhs, rhs)
if #lhs ~= #rhs then
    if #lhs ~= #rhs then
return false
        return false
end
    end
for i = 1, #lhs do
    for i = 1, #lhs do
if lhs[i] ~= rhs[i] then
        if lhs[i] ~= rhs[i] then
return false
            return false
end
        end
end
    end
return true
    return true
end
end


function arr.all(array, fn)
function arr.all(array, fn)
checkType('Module:Array.all', 1, array, 'table')
    checkType('Module:Array.all', 1, array, 'table')
if fn == nil then fn = function(item) return item end end
    if fn == nil then fn = function(item) return item end end
if type(fn) ~= 'function' then
    if type(fn) ~= 'function' then
local val = fn
        local val = fn
fn = function(item) return item == val end
        fn = function(item) return item == val end
end
    end
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
if not fn(array[i], i) then
        if not fn(array[i], i) then
return false
            return false
end
        end
i = i + 1
        i = i + 1
end
    end
return true
    return true
end
end


function arr.any(array, fn)
function arr.any(array, fn)
checkType('Module:Array.any', 1, array, 'table')
    checkType('Module:Array.any', 1, array, 'table')
if fn == nil then fn = function(item) return item end end
    if fn == nil then fn = function(item) return item end end
if type(fn) ~= 'function' then
    if type(fn) ~= 'function' then
local val = fn
        local val = fn
fn = function(item) return item == val end
        fn = function(item) return item == val end
end
    end
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
if fn(array[i], i) then
        if fn(array[i], i) then
return true
            return true
end
        end
i = i + 1
        i = i + 1
end
    end
return false
    return false
end
end


function arr.clean(array)
function arr.clean(array)
checkType('Module:Array.clean', 1, array, 'table')
    checkType('Module:Array.clean', 1, array, 'table')
for i = 1, #array do
    for i = 1, #array do
if type(array[i]) == 'table' then
        if type(array[i]) == 'table' then
arr.clean(array[i])
            arr.clean(array[i])
end
        end
end
    end
setmetatable(array, nil)
    setmetatable(array, nil)
return array
    return array
end
end


function arr.contains(array, elem, useElemTableContent)
function arr.contains(array, elem, useElemTableContent)
checkType('Module:Array.contains', 1, array, 'table')
    checkType('Module:Array.contains', 1, array, 'table')
if type(elem) == 'table' and useElemTableContent ~= false then
    if type(elem) == 'table' and useElemTableContent ~= false then
local elemMap = {}
        local elemMap = {}
local isFound = {}
        local isFound = {}
arr.each(elem, function(x, i) elemMap[x] = i; isFound[i] = false end)
        arr.each(elem, function(x, i) elemMap[x] = i; isFound[i] = false end)
for i = 1, #array do
        for i = 1, #array do
local j = elemMap[array[i]]
            local j = elemMap[array[i]]
if j then
            if j then
isFound[j] = true
                isFound[j] = true
end
            end
end
        end
return arr.all(isFound, true)
        return arr.all(isFound, true)
else
    else
return arr.any(array, function(item) return item == elem end)
        return arr.any(array, function(item) return item == elem end)
end
    end
end
end


function arr.count(array, fn)
function arr.count(array, fn)
checkType('Module:Array.count', 1, array, 'table')
    checkType('Module:Array.count', 1, array, 'table')
if fn == nil then fn = function(item) return item end end
    if fn == nil then fn = function(item) return item end end
if type(fn) ~= 'function' then
    if type(fn) ~= 'function' then
local val = fn
        local val = fn
fn = function(item) return item == val end
        fn = function(item) return item == val end
end
    end
local count = 0
    local count = 0
for i = 1, #array do
    for i = 1, #array do
if fn(array[i]) then
        if fn(array[i]) then
count = count + 1
            count = count + 1
end
        end
end
    end
return count
    return count
end
end


function arr.diff(array, order)
function arr.diff(array, order)
checkType('Module:Array.diff', 1, array, 'table')
    checkType('Module:Array.diff', 1, array, 'table')
checkType('Module:Array.diff', 2, order, 'number', true)
    checkType('Module:Array.diff', 2, order, 'number', true)
local res = setmetatable({}, getmetatable(array))
    local res = setmetatable({}, getmetatable(array))
for i = 1, #array - 1 do
    for i = 1, #array - 1 do
res[i] = array[i+1] - array[i]
        res[i] = array[i+1] - array[i]
end
    end
if order and order > 1 then
    if order and order > 1 then
return arr.diff(res, order - 1)
        return arr.diff(res, order - 1)
end
    end
return res
    return res
end
end


function arr.each(array, fn)
function arr.each(array, fn)
checkType('Module:Array.each', 1, array, 'table')
    checkType('Module:Array.each', 1, array, 'table')
checkType('Module:Array.each', 2, fn, 'function')
    checkType('Module:Array.each', 2, fn, 'function')
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
fn(array[i], i)
        fn(array[i], i)
i = i + 1
        i = i + 1
end
    end
end
end


function arr.filter(array, fn)
function arr.filter(array, fn)
checkType('Module:Array.filter', 1, array, 'table')
    checkType('Module:Array.filter', 1, array, 'table')
if fn == nil then fn = function(item) return item end end
    if fn == nil then fn = function(item) return item end end
if type(fn) ~= 'function' then
    if type(fn) ~= 'function' then
local val = fn
        local val = fn
fn = function(item) return item == val end
        fn = function(item) return item == val end
end
    end
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local len = 0
    local len = 0
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
if fn(array[i], i) then
        if fn(array[i], i) then
len = len + 1
            len = len + 1
r[len] = array[i]
            r[len] = array[i]
end
        end
i = i + 1
        i = i + 1
end
    end
return r
    return r
end
end


function arr.find(array, fn, default)
function arr.find(array, fn, default)
checkType('Module:Array.find', 1, array, 'table')
    checkType('Module:Array.find', 1, array, 'table')
checkTypeMulti('Module:Array.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
    checkTypeMulti('Module:Array.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
if type(fn) ~= 'function' then
    if type(fn) ~= 'function' then
local val = fn
        local val = fn
fn = function(item) return item == val end
        fn = function(item) return item == val end
end
    end
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
if fn(array[i], i) then
        if fn(array[i], i) then
return array[i], i
            return array[i], i
end
        end
i = i + 1
        i = i + 1
end
    end
return default
    return default
end
end


function arr.find_index(array, fn, default)
function arr.find_index(array, fn, default)
checkType('Module:Array.find_index', 1, array, 'table')
    checkType('Module:Array.find_index', 1, array, 'table')
checkTypeMulti('Module:Array.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
    checkTypeMulti('Module:Array.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
if type(fn) ~= 'function' then
    if type(fn) ~= 'function' then
local val = fn
        local val = fn
fn = function(item) return item == val end
        fn = function(item) return item == val end
end
    end
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
if fn(array[i], i) then
        if fn(array[i], i) then
return i
            return i
end
        end
i = i + 1
        i = i + 1
end
    end
return default
    return default
end
end


function arr.newIncrementor(start, step)
function arr.newIncrementor(start, step)
checkType('Module:Array.newIncrementor', 1, start, 'number', true)
    checkType('Module:Array.newIncrementor', 1, start, 'number', true)
checkType('Module:Array.newIncrementor', 2, step, 'number', true)
    checkType('Module:Array.newIncrementor', 2, step, 'number', true)
step = step or 1
    step = step or 1
local n = (start or 1) - step
    local n = (start or 1) - step
local obj = {}
    local obj = {}
return setmetatable(obj, {
    return setmetatable(obj, {
__call = function() n = n + step return n end,
        __call = function() n = n + step return n end,
__tostring = function() return n end,
        __tostring = function() return n end,
__index = function() return n end,
        __index = function() return n end,
__newindex = function(self, k, v)
        __newindex = function(self, k, v)
if k == 'step' and type(v) == 'number' then
            if k == 'step' and type(v) == 'number' then
step = v
                step = v
elseif type(v) == 'number' then
            elseif type(v) == 'number' then
n = v
                n = v
end
            end
end,
        end,
__concat = function(x, y) return tostring(x) .. tostring(y) end
        __concat = function(x, y) return tostring(x) .. tostring(y) end
})
    })
end
end


function arr.int(array, start, stop)
function arr.int(array, start, stop)
checkType('Module:Array.int', 1, array, 'table')
    checkType('Module:Array.int', 1, array, 'table')
checkType('Module:Array.int', 2, start, 'number', true)
    checkType('Module:Array.int', 2, start, 'number', true)
checkType('Module:Array.int', 3, stop, 'number', true)
    checkType('Module:Array.int', 3, stop, 'number', true)
local res = setmetatable({}, getmetatable(array))
    local res = setmetatable({}, getmetatable(array))
start = start or 1
    start = start or 1
stop = stop or #array
    stop = stop or #array
res[1] = array[start]
    res[1] = array[start]
for i = 1, stop - start do
    for i = 1, stop - start do
res[i+1] = res[i] + array[start + i]
        res[i+1] = res[i] + array[start + i]
end
    end
return res
    return res
end
end


function arr.intersect(array1, array2)
function arr.intersect(array1, array2)
checkType('Module:Array.intersect', 1, array1, 'table')
    checkType('Module:Array.intersect', 1, array1, 'table')
checkType('Module:Array.intersect', 2, array2, 'table')
    checkType('Module:Array.intersect', 2, array2, 'table')
local array2Elements = {}
    local array2Elements = {}
local res = setmetatable({}, getmetatable(array1) or getmetatable(array2))
    local res = setmetatable({}, getmetatable(array1) or getmetatable(array2))
local len = 0
    local len = 0
arr.each(array2, function(item) array2Elements[item] = true end)
    arr.each(array2, function(item) array2Elements[item] = true end)
arr.each(array1, function(item)
    arr.each(array1, function(item)
if array2Elements[item] then
        if array2Elements[item] then
len = len + 1
            len = len + 1
res[len] = item
            res[len] = item
end
        end
end)
    end)
return res
    return res
end
end


function arr.intersects(array1, array2)
function arr.intersects(array1, array2)
checkType('Module:Array.intersects', 1, array1, 'table')
    checkType('Module:Array.intersects', 1, array1, 'table')
checkType('Module:Array.intersects', 2, array2, 'table')
    checkType('Module:Array.intersects', 2, array2, 'table')
local small = {}
    local small = {}
local large
    local large
if #array1 <= #array2 then
    if #array1 <= #array2 then
arr.each(array1, function(item) small[item] = true end)
        arr.each(array1, function(item) small[item] = true end)
large = array2
        large = array2
else
    else
arr.each(array2, function(item) small[item] = true end)
        arr.each(array2, function(item) small[item] = true end)
large = array1
        large = array1
end
    end
return arr.any(large, function(item) return small[item] end)
    return arr.any(large, function(item) return small[item] end)
end
end


function arr.insert(array, val, index, unpackVal)
function arr.insert(array, val, index, unpackVal)
checkType('Module:Array.insert', 1, array, 'table')
    checkType('Module:Array.insert', 1, array, 'table')
checkType('Module:Array.insert', 3, index, 'number', true)
    checkType('Module:Array.insert', 3, index, 'number', true)
checkType('Module:Array.insert', 4, unpackVal, 'boolean', true)
    checkType('Module:Array.insert', 4, unpackVal, 'boolean', true)
local len = #array
    local len = #array
index = index or (len + 1)
    index = index or (len + 1)


if type(val) == 'table' and unpackVal ~= false then
    if type(val) == 'table' and unpackVal ~= false then
local len2 = #val
        local len2 = #val
for i = 0, len - index do
        for i = 0, len - index do
array[len + len2 - i] = array[len - i]
            array[len + len2 - i] = array[len - i]
end
        end
for i = 0, len2 - 1 do
        for i = 0, len2 - 1 do
array[index + i] = val[i + 1]
            array[index + i] = val[i + 1]
end
        end
else
    else
table.insert(array, index, val)
        table.insert(array, index, val)
end
    end


return array
    return array
end
end


function arr.map(array, fn)
function arr.map(array, fn)
checkType('Module:Array.map', 1, array, 'table')
    checkType('Module:Array.map', 1, array, 'table')
checkType('Module:Array.map', 2, fn, 'function')
    checkType('Module:Array.map', 2, fn, 'function')
local len = 0
    local len = 0
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
local tmp = fn(array[i], i)
        local tmp = fn(array[i], i)
if tmp ~= nil then
        if tmp ~= nil then
len = len + 1
            len = len + 1
r[len] = tmp
            r[len] = tmp
end
        end
i = i + 1
        i = i + 1
end
    end
return r
    return r
end
end


function arr.max_by(array, fn)
function arr.max_by(array, fn)
checkType('Module:Array.max_by', 1, array, 'table')
    checkType('Module:Array.max_by', 1, array, 'table')
checkType('Module:Array.max_by', 2, fn, 'function')
    checkType('Module:Array.max_by', 2, fn, 'function')
return unpack(arr.reduce(array, function(new, old, i)
    return unpack(arr.reduce(array, function(new, old, i)
local y = fn(new)
        local y = fn(new)
return y > old[2] and {new, y, i} or old
        return y > old[2] and {new, y, i} or old
end, {nil, -math.huge}))
    end, {nil, -math.huge}))
end
end


function arr.max(array)
function arr.max(array)
checkType('Module:Array.max', 1, array, 'table')
    checkType('Module:Array.max', 1, array, 'table')
local val, _, i = arr.max_by(array, function(x) return x end)
    local val, _, i = arr.max_by(array, function(x) return x end)
return val, i
    return val, i
end
end


function arr.min(array)
function arr.min(array)
checkType('Module:Array.min', 1, array, 'table')
    checkType('Module:Array.min', 1, array, 'table')
local val, _, i = arr.max_by(array, function(x) return -x end)
    local val, _, i = arr.max_by(array, function(x) return -x end)
return val, i
    return val, i
end
end


function arr.new(array)
function arr.new(array)
array = array or {}
    array = array or {}
for _, v in pairs(array) do
    for _, v in pairs(array) do
if type(v) == 'table' then
        if type(v) == 'table' then
arr.new(v)
            arr.new(v)
end
        end
end
    end


if getmetatable(array) == nil then
    if getmetatable(array) == nil then
setmetatable(array, arr)
        setmetatable(array, arr)
end
    end


return array
    return array
end
end


function arr.range(start, stop, step)
function arr.range(start, stop, step)
checkType('Module:Array.range', 1, start, 'number')
    checkType('Module:Array.range', 1, start, 'number')
checkType('Module:Array.range', 2, stop, 'number', true)
    checkType('Module:Array.range', 2, stop, 'number', true)
checkType('Module:Array.range', 3, step, 'number', true)
    checkType('Module:Array.range', 3, step, 'number', true)
local array = setmetatable({}, arr)
    local array = setmetatable({}, arr)
local len = 0
    local len = 0
if not stop then
    if not stop then
stop = start
        stop = start
start = 1
        start = 1
end
    end
for i = start, stop, step or 1 do
    for i = start, stop, step or 1 do
len = len + 1
        len = len + 1
array[len] = i
        array[len] = i
end
    end
return array
    return array
end
end


function arr.reduce(array, fn, accumulator)
function arr.reduce(array, fn, accumulator)
checkType('Module:Array.reduce', 1, array, 'table')
    checkType('Module:Array.reduce', 1, array, 'table')
checkType('Module:Array.reduce', 2, fn, 'function')
    checkType('Module:Array.reduce', 2, fn, 'function')
local acc = accumulator
    local acc = accumulator
local i = 1
    local i = 1
if acc == nil then
    if acc == nil then
acc = array[1]
        acc = array[1]
i = 2
        i = 2
end
    end
while array[i] ~= nil do
    while array[i] ~= nil do
acc = fn(array[i], acc, i)
        acc = fn(array[i], acc, i)
i = i + 1
        i = i + 1
end
    end
return acc
    return acc
end
end


function arr.reject(array, fn)
function arr.reject(array, fn)
checkType('Module:Array.reject', 1, array, 'table')
    checkType('Module:Array.reject', 1, array, 'table')
checkTypeMulti('Module:Array.reject', 2, fn, {'function', 'table', 'number', 'boolean'})
    checkTypeMulti('Module:Array.reject', 2, fn, {'function', 'table', 'number', 'boolean'})
if fn == nil then fn = function(item) return item end end
    if fn == nil then fn = function(item) return item end end
if type(fn) ~= 'function' and type(fn) ~= 'table' then
    if type(fn) ~= 'function' and type(fn) ~= 'table' then
fn = {fn}
        fn = {fn}
end
    end
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local len = 0
    local len = 0
if type(fn) == 'function' then
    if type(fn) == 'function' then
local i = 1
        local i = 1
while array[i] ~= nil do
        while array[i] ~= nil do
if not fn(array[i], i) then
            if not fn(array[i], i) then
len = len + 1
                len = len + 1
r[len] = array[i]
                r[len] = array[i]
end
            end
i = i + 1
            i = i + 1
end
        end
else
    else
local rejectMap = {}
        local rejectMap = {}
arr.each(fn, function(item) rejectMap[item] = true end)
        arr.each(fn, function(item) rejectMap[item] = true end)
local i = 1
        local i = 1
while array[i] ~= nil do
        while array[i] ~= nil do
if not rejectMap[array[i]] then
            if not rejectMap[array[i]] then
len = len + 1
                len = len + 1
r[len] = array[i]
                r[len] = array[i]
end
            end
i = i + 1
            i = i + 1
end
        end
end
    end
return r
    return r
end
end


function arr.rep(val, n)
function arr.rep(val, n)
checkType('Module:Array.rep', 2, n, 'number')
    checkType('Module:Array.rep', 2, n, 'number')
local r = setmetatable({}, arr)
    local r = setmetatable({}, arr)
for i = 1, n do
    for i = 1, n do
r[i] = val
        r[i] = val
end
    end
return r
    return r
end
end


function arr.scan(array, fn, accumulator)
function arr.scan(array, fn, accumulator)
checkType('Module:Array.scan', 1, array, 'table')
    checkType('Module:Array.scan', 1, array, 'table')
checkType('Module:Array.scan', 2, fn, 'function')
    checkType('Module:Array.scan', 2, fn, 'function')
local acc = accumulator
    local acc = accumulator
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
if i == 1 and not accumulator then
        if i == 1 and not accumulator then
acc = array[i]
            acc = array[i]
else
        else
acc = fn(array[i], acc)
            acc = fn(array[i], acc)
end
        end
r[i] = acc
        r[i] = acc
i = i + 1
        i = i + 1
end
    end
return r
    return r
end
end


function arr.slice(array, start, finish)
function arr.slice(array, start, finish)
checkType('Module:Array.slice', 1, array, 'table')
    checkType('Module:Array.slice', 1, array, 'table')
checkType('Module:Array.slice', 2, start, 'number', true)
    checkType('Module:Array.slice', 2, start, 'number', true)
checkType('Module:Array.slice', 3, finish, 'number', true)
    checkType('Module:Array.slice', 3, finish, 'number', true)
start = start or 1
    start = start or 1
finish = finish or #array
    finish = finish or #array
if start < 0 and finish == nil then
    if start < 0 and finish == nil then
finish = #array + start
        finish = #array + start
start = 1
        start = 1
elseif start < 0 then
    elseif start < 0 then
start = #array + start
        start = #array + start
end
    end
if finish < 0 then
    if finish < 0 then
finish = #array + finish
        finish = #array + finish
end
    end
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local len = 0
    local len = 0
for i = start, finish do
    for i = start, finish do
len = len + 1
        len = len + 1
r[len] = array[i]
        r[len] = array[i]
end
    end
return r
    return r
end
end


function arr.split(array, count)
function arr.split(array, count)
checkType('Module:Array.split', 1, array, 'table')
    checkType('Module:Array.split', 1, array, 'table')
checkType('Module:Array.split', 2, count, 'number')
    checkType('Module:Array.split', 2, count, 'number')
local x = setmetatable({}, getmetatable(array))
    local x = setmetatable({}, getmetatable(array))
local y = setmetatable({}, getmetatable(array))
    local y = setmetatable({}, getmetatable(array))
for i = 1, #array do
    for i = 1, #array do
table.insert(i <= count and x or y, array[i])
        table.insert(i <= count and x or y, array[i])
end
    end
return x, y
    return x, y
end
end


function arr.sum(array)
function arr.sum(array)
checkType('Module:Array.sum', 1, array, 'table')
    checkType('Module:Array.sum', 1, array, 'table')
local res = 0
    local res = 0
for i = 1, #array do
    for i = 1, #array do
res = res + array[i]
        res = res + array[i]
end
    end
return res
    return res
end
end


function arr.take(array, count, offset)
function arr.take(array, count, offset)
checkType('Module:Array.take', 1, array, 'table')
    checkType('Module:Array.take', 1, array, 'table')
checkType('Module:Array.take', 2, count, 'number')
    checkType('Module:Array.take', 2, count, 'number')
checkType('Module:Array.take', 3, offset, 'number', true)
    checkType('Module:Array.take', 3, offset, 'number', true)
local x = setmetatable({}, getmetatable(array))
    local x = setmetatable({}, getmetatable(array))
for i = offset or 1, #array do
    for i = offset or 1, #array do
if i <= count then
        if i <= count then
table.insert(x, array[i])
            table.insert(x, array[i])
end
        end
end
    end
return x
    return x
end
end


function arr.take_every(array, n, offset)
function arr.take_every(array, n, offset)
checkType('Module:Array.take_every', 1, array, 'table')
    checkType('Module:Array.take_every', 1, array, 'table')
checkType('Module:Array.take_every', 2, n, 'number')
    checkType('Module:Array.take_every', 2, n, 'number')
checkType('Module:Array.take_every', 3, offset, 'number', true)
    checkType('Module:Array.take_every', 3, offset, 'number', true)
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local len = 0
    local len = 0
local i = offset or 1
    local i = offset or 1
while array[i] ~= nil do
    while array[i] ~= nil do
len = len + 1
        len = len + 1
r[len] = array[i]
        r[len] = array[i]
i = i + n
        i = i + n
end
    end
return r
    return r
end
end


function arr.unique(array, fn)
function arr.unique(array, fn)
checkType('Module:Array.unique', 1, array, 'table')
    checkType('Module:Array.unique', 1, array, 'table')
checkType('Module:Array.unique', 2, fn, 'function', true)
    checkType('Module:Array.unique', 2, fn, 'function', true)
fn = fn or function(item) return item end
    fn = fn or function(item) return item end
local r = setmetatable({}, getmetatable(array))
    local r = setmetatable({}, getmetatable(array))
local len = 0
    local len = 0
local hash = {}
    local hash = {}
local i = 1
    local i = 1
while array[i] ~= nil do
    while array[i] ~= nil do
local id = fn(array[i])
        local id = fn(array[i])
if not hash[id] then
        if not hash[id] then
len = len + 1
            len = len + 1
r[len] = array[i]
            r[len] = array[i]
hash[id] = true
            hash[id] = true
end
        end
i = i + 1
        i = i + 1
end
    end
return r
    return r
end
end


function arr.update(array, indexes, values)
function arr.update(array, indexes, values)
checkType('Module:Array.update', 1, array, 'table')
    checkType('Module:Array.update', 1, array, 'table')
checkTypeMulti('Module:Array.update', 2, indexes, {'table', 'number'})
    checkTypeMulti('Module:Array.update', 2, indexes, {'table', 'number'})
if type(indexes) == 'number' then
    if type(indexes) == 'number' then
indexes = {indexes}
        indexes = {indexes}
end
    end
if type(values) == 'table' then
    if type(values) == 'table' then
assert(#indexes == #values, 'Values array must be of equal length as index array')
        assert(#indexes == #values, 'Values array must be of equal length as index array')
for i = 1, #indexes do
        for i = 1, #indexes do
array[indexes[i]] = values[i]
            array[indexes[i]] = values[i]
end
        end
else
    else
for i = 1, #indexes do
        for i = 1, #indexes do
array[indexes[i]] = values
            array[indexes[i]] = values
end
        end
end
    end
return array
    return array
end
end


function arr.zip(...)
function arr.zip(...)
local arrays = { ... }
    local arrays = { ... }
checkType('Module:Array.zip', 1, arrays[1], 'table')
    checkType('Module:Array.zip', 1, arrays[1], 'table')
local r = setmetatable({}, getmetatable(arrays[1]))
    local r = setmetatable({}, getmetatable(arrays[1]))
local _, longest = arr.max_by(arrays, function(array) return #array end)
    local _, longest = arr.max_by(arrays, function(array) return #array end)
for i = 1, longest do
    for i = 1, longest do
local q = {}
        local q = {}
for j = 1, #arrays do
        for j = 1, #arrays do
table.insert(q, arrays[j][i])
            table.insert(q, arrays[j][i])
end
        end
table.insert(r, q)
        table.insert(r, q)
end
    end
return r
    return r
end
end


return arr
return arr
-- </nowiki>
-- </nowiki>

Revision as of 12:09, 24 June 2023

Documentation for this module may be created at Module:Array/doc

-- Imported from: https://runescape.wiki/w/Module:Array

-- <nowiki>
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
local arr = {}

setmetatable(arr, {
    __call = function (_, array)
        return arr.new(array)
    end
})

function arr.__index(t, k)
    if type(k) == 'table' then
        local res = arr.new()
        for i = 1, #t do
            res[i] = t[k[i]]
        end
        return res
    else
        return arr[k]
    end
end

function arr.__tostring(array)
    local dumpObject = require('Module:Logger').dumpObject
    setmetatable(array, nil)
    local str = dumpObject(array, {clean=true, collapseLimit=100})
    setmetatable(array, arr)
    return str
end

function arr.__concat(lhs, rhs)
    if type(lhs) == 'table' and type(rhs) == 'table' then
        local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs))
        for i = 1, #lhs do
            res[i] = lhs[i]
        end
        local l = #lhs
        for i = 1, #rhs do
            res[i + l] = rhs[i]
        end
        return res
    else
        return tostring(lhs) .. tostring(rhs)
    end
end

function arr.__unm(array)
    return arr.map(array, function(x) return -x end)
end

local function mathTemplate(lhs, rhs, funName, fun)
    checkTypeMulti('Module:Array.' .. funName, 1, lhs, {'number', 'table'})
    checkTypeMulti('Module:Array.' .. funName, 2, rhs, {'number', 'table'})
    local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs))

    if type(lhs) == 'number' then
        for i = 1, #rhs do
            res[i] = fun(lhs, rhs[i])
        end
    elseif type(rhs) == 'number' then
        for i = 1, #lhs do
            res[i] = fun(lhs[i], rhs)
        end
    else
        assert(#lhs == #rhs, string.format('Tables are not equal length (lhs=%d, rhs=%d)', #lhs, #rhs))
        for i = 1, #lhs do
            res[i] = fun(lhs[i], rhs[i])
        end
    end

    return res
end

function arr.__add(lhs, rhs)
    return mathTemplate(lhs, rhs, '__add', function(x, y) return x + y end)
end

function arr.__sub(lhs, rhs)
    return mathTemplate(lhs, rhs, '__sub', function(x, y) return x - y end)
end

function arr.__mul(lhs, rhs)
    return mathTemplate(lhs, rhs, '__mul', function(x, y) return x * y end)
end

function arr.__div(lhs, rhs)
    return mathTemplate(lhs, rhs, '__div', function(x, y) return x / y end)
end

function arr.__pow(lhs, rhs)
    return mathTemplate(lhs, rhs, '__pow', function(x, y) return x ^ y end)
end

function arr.__lt(lhs, rhs)
    for i = 1, math.min(#lhs, #rhs) do
        if lhs[i] >= rhs[i] then
            return false
        end
    end
    return true
end

function arr.__le(lhs, rhs)
    for i = 1, math.min(#lhs, #rhs) do
        if lhs[i] > rhs[i] then
            return false
        end
    end
    return true
end

function arr.__eq(lhs, rhs)
    if #lhs ~= #rhs then
        return false
    end
    for i = 1, #lhs do
        if lhs[i] ~= rhs[i] then
            return false
        end
    end
    return true
end

function arr.all(array, fn)
    checkType('Module:Array.all', 1, array, 'table')
    if fn == nil then fn = function(item) return item end end
    if type(fn) ~= 'function' then
        local val = fn
        fn = function(item) return item == val end
    end
    local i = 1
    while array[i] ~= nil do
        if not fn(array[i], i) then
            return false
        end
        i = i + 1
    end
    return true
end

function arr.any(array, fn)
    checkType('Module:Array.any', 1, array, 'table')
    if fn == nil then fn = function(item) return item end end
    if type(fn) ~= 'function' then
        local val = fn
        fn = function(item) return item == val end
    end
    local i = 1
    while array[i] ~= nil do
        if fn(array[i], i) then
            return true
        end
        i = i + 1
    end
    return false
end

function arr.clean(array)
    checkType('Module:Array.clean', 1, array, 'table')
    for i = 1, #array do
        if type(array[i]) == 'table' then
            arr.clean(array[i])
        end
    end
    setmetatable(array, nil)
    return array
end

function arr.contains(array, elem, useElemTableContent)
    checkType('Module:Array.contains', 1, array, 'table')
    if type(elem) == 'table' and useElemTableContent ~= false then
        local elemMap = {}
        local isFound = {}
        arr.each(elem, function(x, i) elemMap[x] = i; isFound[i] = false end)
        for i = 1, #array do
            local j = elemMap[array[i]]
            if j then
                isFound[j] = true
            end
        end
        return arr.all(isFound, true)
    else
        return arr.any(array, function(item) return item == elem end)
    end
end

function arr.count(array, fn)
    checkType('Module:Array.count', 1, array, 'table')
    if fn == nil then fn = function(item) return item end end
    if type(fn) ~= 'function' then
        local val = fn
        fn = function(item) return item == val end
    end
    local count = 0
    for i = 1, #array do
        if fn(array[i]) then
            count = count + 1
        end
    end
    return count
end

function arr.diff(array, order)
    checkType('Module:Array.diff', 1, array, 'table')
    checkType('Module:Array.diff', 2, order, 'number', true)
    local res = setmetatable({}, getmetatable(array))
    for i = 1, #array - 1 do
        res[i] = array[i+1] - array[i]
    end
    if order and order > 1 then
        return arr.diff(res, order - 1)
    end
    return res
end

function arr.each(array, fn)
    checkType('Module:Array.each', 1, array, 'table')
    checkType('Module:Array.each', 2, fn, 'function')
    local i = 1
    while array[i] ~= nil do
        fn(array[i], i)
        i = i + 1
    end
end

function arr.filter(array, fn)
    checkType('Module:Array.filter', 1, array, 'table')
    if fn == nil then fn = function(item) return item end end
    if type(fn) ~= 'function' then
        local val = fn
        fn = function(item) return item == val end
    end
    local r = setmetatable({}, getmetatable(array))
    local len = 0
    local i = 1
    while array[i] ~= nil do
        if fn(array[i], i) then
            len = len + 1
            r[len] = array[i]
        end
        i = i + 1
    end
    return r
end

function arr.find(array, fn, default)
    checkType('Module:Array.find', 1, array, 'table')
    checkTypeMulti('Module:Array.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
    if type(fn) ~= 'function' then
        local val = fn
        fn = function(item) return item == val end
    end
    local i = 1
    while array[i] ~= nil do
        if fn(array[i], i) then
            return array[i], i
        end
        i = i + 1
    end
    return default
end

function arr.find_index(array, fn, default)
    checkType('Module:Array.find_index', 1, array, 'table')
    checkTypeMulti('Module:Array.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
    if type(fn) ~= 'function' then
        local val = fn
        fn = function(item) return item == val end
    end
    local i = 1
    while array[i] ~= nil do
        if fn(array[i], i) then
            return i
        end
        i = i + 1
    end
    return default
end

function arr.newIncrementor(start, step)
    checkType('Module:Array.newIncrementor', 1, start, 'number', true)
    checkType('Module:Array.newIncrementor', 2, step, 'number', true)
    step = step or 1
    local n = (start or 1) - step
    local obj = {}
    return setmetatable(obj, {
        __call = function() n = n + step return n end,
        __tostring = function() return n end,
        __index = function() return n end,
        __newindex = function(self, k, v)
            if k == 'step' and type(v) == 'number' then
                step = v
            elseif type(v) == 'number' then
                n = v
            end
        end,
        __concat = function(x, y) return tostring(x) .. tostring(y) end
    })
end

function arr.int(array, start, stop)
    checkType('Module:Array.int', 1, array, 'table')
    checkType('Module:Array.int', 2, start, 'number', true)
    checkType('Module:Array.int', 3, stop, 'number', true)
    local res = setmetatable({}, getmetatable(array))
    start = start or 1
    stop = stop or #array
    res[1] = array[start]
    for i = 1, stop - start do
        res[i+1] = res[i] + array[start + i]
    end
    return res
end

function arr.intersect(array1, array2)
    checkType('Module:Array.intersect', 1, array1, 'table')
    checkType('Module:Array.intersect', 2, array2, 'table')
    local array2Elements = {}
    local res = setmetatable({}, getmetatable(array1) or getmetatable(array2))
    local len = 0
    arr.each(array2, function(item) array2Elements[item] = true end)
    arr.each(array1, function(item)
        if array2Elements[item] then
            len = len + 1
            res[len] = item
        end
    end)
    return res
end

function arr.intersects(array1, array2)
    checkType('Module:Array.intersects', 1, array1, 'table')
    checkType('Module:Array.intersects', 2, array2, 'table')
    local small = {}
    local large
    if #array1 <= #array2 then
        arr.each(array1, function(item) small[item] = true end)
        large = array2
    else
        arr.each(array2, function(item) small[item] = true end)
        large = array1
    end
    return arr.any(large, function(item) return small[item] end)
end

function arr.insert(array, val, index, unpackVal)
    checkType('Module:Array.insert', 1, array, 'table')
    checkType('Module:Array.insert', 3, index, 'number', true)
    checkType('Module:Array.insert', 4, unpackVal, 'boolean', true)
    local len = #array
    index = index or (len + 1)

    if type(val) == 'table' and unpackVal ~= false then
        local len2 = #val
        for i = 0, len - index do
            array[len + len2 - i] = array[len - i]
        end
        for i = 0, len2 - 1 do
            array[index + i] = val[i + 1]
        end
    else
        table.insert(array, index, val)
    end

    return array
end

function arr.map(array, fn)
    checkType('Module:Array.map', 1, array, 'table')
    checkType('Module:Array.map', 2, fn, 'function')
    local len = 0
    local r = setmetatable({}, getmetatable(array))
    local i = 1
    while array[i] ~= nil do
        local tmp = fn(array[i], i)
        if tmp ~= nil then
            len = len + 1
            r[len] = tmp
        end
        i = i + 1
    end
    return r
end

function arr.max_by(array, fn)
    checkType('Module:Array.max_by', 1, array, 'table')
    checkType('Module:Array.max_by', 2, fn, 'function')
    return unpack(arr.reduce(array, function(new, old, i)
        local y = fn(new)
        return y > old[2] and {new, y, i} or old
    end, {nil, -math.huge}))
end

function arr.max(array)
    checkType('Module:Array.max', 1, array, 'table')
    local val, _, i = arr.max_by(array, function(x) return x end)
    return val, i
end

function arr.min(array)
    checkType('Module:Array.min', 1, array, 'table')
    local val, _, i = arr.max_by(array, function(x) return -x end)
    return val, i
end

function arr.new(array)
    array = array or {}
    for _, v in pairs(array) do
        if type(v) == 'table' then
            arr.new(v)
        end
    end

    if getmetatable(array) == nil then
        setmetatable(array, arr)
    end

    return array
end

function arr.range(start, stop, step)
    checkType('Module:Array.range', 1, start, 'number')
    checkType('Module:Array.range', 2, stop, 'number', true)
    checkType('Module:Array.range', 3, step, 'number', true)
    local array = setmetatable({}, arr)
    local len = 0
    if not stop then
        stop = start
        start = 1
    end
    for i = start, stop, step or 1 do
        len = len + 1
        array[len] = i
    end
    return array
end

function arr.reduce(array, fn, accumulator)
    checkType('Module:Array.reduce', 1, array, 'table')
    checkType('Module:Array.reduce', 2, fn, 'function')
    local acc = accumulator
    local i = 1
    if acc == nil then
        acc = array[1]
        i = 2
    end
    while array[i] ~= nil do
        acc = fn(array[i], acc, i)
        i = i + 1
    end
    return acc
end

function arr.reject(array, fn)
    checkType('Module:Array.reject', 1, array, 'table')
    checkTypeMulti('Module:Array.reject', 2, fn, {'function', 'table', 'number', 'boolean'})
    if fn == nil then fn = function(item) return item end end
    if type(fn) ~= 'function' and type(fn) ~= 'table' then
        fn = {fn}
    end
    local r = setmetatable({}, getmetatable(array))
    local len = 0
    if type(fn) == 'function' then
        local i = 1
        while array[i] ~= nil do
            if not fn(array[i], i) then
                len = len + 1
                r[len] = array[i]
            end
            i = i + 1
        end
    else
        local rejectMap = {}
        arr.each(fn, function(item) rejectMap[item] = true end)
        local i = 1
        while array[i] ~= nil do
            if not rejectMap[array[i]] then
                len = len + 1
                r[len] = array[i]
            end
            i = i + 1
        end
    end
    return r
end

function arr.rep(val, n)
    checkType('Module:Array.rep', 2, n, 'number')
    local r = setmetatable({}, arr)
    for i = 1, n do
        r[i] = val
    end
    return r
end

function arr.scan(array, fn, accumulator)
    checkType('Module:Array.scan', 1, array, 'table')
    checkType('Module:Array.scan', 2, fn, 'function')
    local acc = accumulator
    local r = setmetatable({}, getmetatable(array))
    local i = 1
    while array[i] ~= nil do
        if i == 1 and not accumulator then
            acc = array[i]
        else
            acc = fn(array[i], acc)
        end
        r[i] = acc
        i = i + 1
    end
    return r
end

function arr.slice(array, start, finish)
    checkType('Module:Array.slice', 1, array, 'table')
    checkType('Module:Array.slice', 2, start, 'number', true)
    checkType('Module:Array.slice', 3, finish, 'number', true)
    start = start or 1
    finish = finish or #array
    if start < 0 and finish == nil then
        finish = #array + start
        start = 1
    elseif start < 0 then
        start = #array + start
    end
    if finish < 0 then
        finish = #array + finish
    end
    local r = setmetatable({}, getmetatable(array))
    local len = 0
    for i = start, finish do
        len = len + 1
        r[len] = array[i]
    end
    return r
end

function arr.split(array, count)
    checkType('Module:Array.split', 1, array, 'table')
    checkType('Module:Array.split', 2, count, 'number')
    local x = setmetatable({}, getmetatable(array))
    local y = setmetatable({}, getmetatable(array))
    for i = 1, #array do
        table.insert(i <= count and x or y, array[i])
    end
    return x, y
end

function arr.sum(array)
    checkType('Module:Array.sum', 1, array, 'table')
    local res = 0
    for i = 1, #array do
        res = res + array[i]
    end
    return res
end

function arr.take(array, count, offset)
    checkType('Module:Array.take', 1, array, 'table')
    checkType('Module:Array.take', 2, count, 'number')
    checkType('Module:Array.take', 3, offset, 'number', true)
    local x = setmetatable({}, getmetatable(array))
    for i = offset or 1, #array do
        if i <= count then
            table.insert(x, array[i])
        end
    end
    return x
end

function arr.take_every(array, n, offset)
    checkType('Module:Array.take_every', 1, array, 'table')
    checkType('Module:Array.take_every', 2, n, 'number')
    checkType('Module:Array.take_every', 3, offset, 'number', true)
    local r = setmetatable({}, getmetatable(array))
    local len = 0
    local i = offset or 1
    while array[i] ~= nil do
        len = len + 1
        r[len] = array[i]
        i = i + n
    end
    return r
end

function arr.unique(array, fn)
    checkType('Module:Array.unique', 1, array, 'table')
    checkType('Module:Array.unique', 2, fn, 'function', true)
    fn = fn or function(item) return item end
    local r = setmetatable({}, getmetatable(array))
    local len = 0
    local hash = {}
    local i = 1
    while array[i] ~= nil do
        local id = fn(array[i])
        if not hash[id] then
            len = len + 1
            r[len] = array[i]
            hash[id] = true
        end
        i = i + 1
    end
    return r
end

function arr.update(array, indexes, values)
    checkType('Module:Array.update', 1, array, 'table')
    checkTypeMulti('Module:Array.update', 2, indexes, {'table', 'number'})
    if type(indexes) == 'number' then
        indexes = {indexes}
    end
    if type(values) == 'table' then
        assert(#indexes == #values, 'Values array must be of equal length as index array')
        for i = 1, #indexes do
            array[indexes[i]] = values[i]
        end
    else
        for i = 1, #indexes do
            array[indexes[i]] = values
        end
    end
    return array
end

function arr.zip(...)
    local arrays = { ... }
    checkType('Module:Array.zip', 1, arrays[1], 'table')
    local r = setmetatable({}, getmetatable(arrays[1]))
    local _, longest = arr.max_by(arrays, function(array) return #array end)
    for i = 1, longest do
        local q = {}
        for j = 1, #arrays do
            table.insert(q, arrays[j][i])
        end
        table.insert(r, q)
    end
    return r
end

return arr
-- </nowiki>