Function list |
---|
This module is a helper module to be used by other modules; it may not designed to be invoked directly. See Star Citizen:Lua/Helper modules for a full list and more information. For a full list of modules using this helper click here
Function | Type | Use |
---|---|---|
all( arr, [fn] ) | arr: any[] fn?: any -> boolean | Behaviour depends on the value of fn :
|
any( arr, [fn] ) | arr: any[] fn?: any -> boolean | Behaviour depends on the value of fn :
|
clean( arr ) | arr: any[] -> any[] | Recursively removes all metatables. |
clone( arr, [deep] ) | arr: any[] deep?: boolean -> any[] | Make a copy of the input table. Preserves metatables. |
contains( arr, val ) | arr: any[] val: any -> boolean | Check if arr contains val . |
containsAny( arr, t ) | arr: any[] t: any[] -> boolean | Check if arr contains any of the values in the table t . |
containsAll( arr, t ) | arr: any[] t: any[] -> boolean | Check if arr contains all values in the table t . |
convolve( x, y ) | x: number[] y: number[] -> number[] | Convolute two number arrays. |
condenseSparse( arr ) | arr: any[] -> any[] | Remove nil values from arr while preserving order. |
count( arr, fn ) | arr: any[] fn: any -> integer | Behaviour depends on value of val :
|
diff( arr, [order|1] ) | arr: number[] order?: number -> number[] | Differentiates arr . The length of the result is #arr - order long. |
each( arr, fn ) | arr: any[] fn: fun(elem: any, i?: integer) | Loops over the array part of arr and passes each element as the first argument to fn . This function returns nothing. |
filter( arr, fn ) | arr: any[] fn: fun(elem: any, i?: integer): boolean -> any[] | Makes a copy of arr with only elements for which fn returned true. |
find( arr, fn, [default] ) | arr: any[] fn: any default?: any -> any?, integer? | Behaviour depends on the value of fn :
|
find_index( arr, fn, [default] ) | arr: any[] fn: any default?: any -> integer? | Behaviour depends on the value of fn :
|
get( arr, indexes ) | arr: any[] indexes: integer|integer[] -> any[] | Extracts a subset of arr . |
int( arr, [start|1], [stop|#arr] ) | arr: number[] start?: number stop?: number -> number[] | Integrates arr from index start to stop . Effectively does <math>\left\{\sum^{n}_{start}{arr[n]} \,\Bigg |
intersect( arr1, arr2 ) | arr1: any[] arr2: any[] -> any[] | Returns an array with elements that are present in both tables. |
intersects( arr1, arr2 ) | arr1: any[] arr2: any[] -> boolean | Checks if the two inputs have at least one element in common. |
insert( arr, val, [index], [unpackVal] ) OR insert( arr, val, [unpackVal] ) | arr: any[] val: any index?: integer unpackVal?: boolean -> any[] | Inserts values into arr . If val is an array and unpackVal is true then the individual elements of val are inserted. index is the location to start the insertion. Default is at the end of arr . |
last( arr ) | arr: any[] -> any | Returns the last element of arr . |
len( arr ) | arr: any[] -> integer | Returns the length of the array but it also works on proxy arrays like mw.loadData or mw.loadJsonData. |
map( arr, fn ) | arr: any[] fn: fun(elem: any, i?: integer): any -> any[] | Returns a new table were each element of arr is modified by fn . |
max_by( arr, fn ) | arr: any[] fn: fun(elem: any): any -> any, integer | Find the element for which fn returned the largest value. The returned value of fn needs to be comparable using the < operator. Returns three values: The element with the largest fn value, its fn result, and its index. |
max( arr ) | arr: any[] -> any, integer | Find the largest value in the array. The values need to be comparable using the < operator. Returns two values: the element and its index. |
min( arr ) | arr: any[] -> any, integer | Find the smallest value in the array. The values need to be comparable using the < operator. Returns two values: the element and its index. |
new( [arr|{}] ) | arr?: any[] -> any[] | Turn the input table into an Array. This makes it possible to use the colon : operator to access the Array methods. It also enables the use of math operators with the array.
local x = arr.new{ 1, 2, 3 }
local y = arr{ 4, 5, 6 } -- Alternative notation
mw.logObject( -x ) --> { -1, -2, -3 }
mw.logObject( x + 2 ) --> { 3, 4, 5 }
mw.logObject( x - 2 ) --> { -1, 0, 1 }
mw.logObject( x * 2 ) --> { 2, 4, 6 }
mw.logObject( x / 2 ) --> { 0.5, 1, 1.5 }
mw.logObject( x ^ 2 ) --> { 1, 4, 9 }
mw.logObject( x + y ) --> { 5, 7, 9 }
mw.logObject( x .. y ) --> { 1, 2, 3, 4, 5, 6 }
mw.logObject( (x .. y):reject{3, 4, 5} ) --> { 1, 2, 6 }
mw.logObject( x:sum() ) --> 6
mw.logObject( x:update( {1, 3}, y:get{2, 3} * 2 ) ) --> { 10, 2, 12 }
|
newIncrementor( [start|1], [step|1] ) | start?: number step?: number -> Incrementor | Returns a new incrementor function. Every time this incrementor function is called it returns a number step higher than the previous call. The current value can be obtained with inc.n or set inc.n = number where inc is an incrementor function. The step size can be changed with inc.step = number . |
range( stop ) OR range( start, stop, [step|1] ) | start: number stop: number step?: number -> number[] | Returns a table containing a sequence of numbers from start to stop (both inclusive if ints, end-exclusive if floats) by step . range(4) produces {1, 2, 3, 4} (start defaults to 1 ). range(0, 4) produces {0, 1, 2, 3, 4} . When step is given, it specifies the increment (or decrement). |
reduce( arr, fn, [accumulator|arr[1]] ) | arr: any[] fn: fun(elem: any, acc: any, i?: integer): any accumulator?: any -> any | Condenses the array into a single value.
For each element If no local t = { 1, 2, 3, 4 }
local sum = arr.reduce( t, function(elem, acc) return acc + elem end ) -- sum == 10
|
reject( arr, val ) | arr: any[] val: any -> any[] | Make a copy off arr with certain values removed.
Behaviour for different values of
|
rep( val, n ) | val: any n: number -> any[] | Returns a table with n copies of val. |
scan( arr, fn, [accumulator|arr[1]] ) | arr: any[] fn: fun(elem: any, acc: any, i?: integer): any accumulator?: any -> any[] | Condenses the array into a single value while saving every accumulator value.
For each element If no local t = { 1, 2, 3, 4 }
local x = arr.scan( t, function(elem, acc) return acc + elem end ) -- x = { 1, 3, 6, 10 }
|
set( arr, indexes, values ) | arr: any[] indexes: integer|integer[] values: any|any[] -> any[] | Update a range of index with a range of values.
If if only one value is given but multiple indexes than that value is set for all those indexes. Ifvalues is a table then it must of the same length as indexes . |
slice( arr, [start|1], [stop|#arr] ) OR slice( arr, stop ) | arr: any[] start?: number stop?: number -> any[] | Returns a table containing all the elements of arr between the start and stop indices. The start and stop indices are inclusive. If start or stop are negative values then they are referenced to the end of the table. |
split( arr, index ) | arr: any[] index: number -> any[], any[] | Split arr into two arrays. Retuns two tables. The first contains elements from [1, index], and the second from [index + 1, #arr]. |
sum( arr ) | arr: number[] -> number | Returns the sum of all elements of arr . |
take( arr, count, [start|1] ) | arr: any[] count: number start?: number -> any[] | Extract a subtable from arr of count elements long starting from the start index. |
take_every( arr, n, [start|1], [count|#arr] ) | arr: any[] n: integer start?: integer count?: integer -> any[] | Extract a subtable from arr .
local t = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
local x = arr.take_every( t, 2 ) --> x = { 1, 3, 5, 7, 9 }
local x = arr.take_every( t, 2, 3 ) --> x = { 3, 5, 7, 9 }
local x = arr.take_every( t, 2, 3, 2 ) --> x = { 3, 5 }
|
unique( arr, [fn] ) | arr: any[] fn?: fun(elem: any): any -> any[] | Return a new table with all duplicates removed. fn is an optional function to generate an id for each element. The result will then contain elements that generated unique ids. The order of first occurance is preserved. |
zip( ... ) | ...any[] -> any[][] | Combine elements with the same index from multiple arrays.
local x = {1, 2, 3}
local y = {4, 5, 6, 7}
local z = arr.zip( x, y ) --> z = { { 1, 4 }, { 2, 5 }, { 3, 6 }, { 7 } }
|
local arr = require( 'Module:Array' )
local x = arr{1, 2, 3, 4, 10}
local y = arr{'a', 'b', 'b', 1}
arr.any( x, function( item ) return item == 3 end ) --> true
arr.all( y, function( item ) return type( item ) == 'string' end ) --> false
arr.map( x, function( item ) return item * 2 end ) --> { 2, 4, 6, 8, 20 }
arr.filter( y, function( item ) return type( item ) == 'string' end ) --> { "a", "b", "b" }
arr.reject( y, function( item ) return type( item ) == 'string' end ) --> { 1 }
arr.find( x, function( item ) return item > 5 end ) --> 10, 5
arr.find_index( y, function( item ) return type( item ) ~= 'string' end ) --> 4
arr.max_by( x, function( item ) return item * 2 end ) --> 10, 20, 5
arr.reduce( x, function( item, acc ) return acc + item*item end, 5 ) --> 135
arr.range( 10, 1, -3 ) --> { 10, 7, 4, 1 }
arr.scan( x, function( item, acc ) return acc + item*item end, 5 ) --> { 6, 10, 19, 35, 135 }
arr.slice( x, 2, 4 ) --> { 2, 3, 4 }
arr.split( x, 2 ) --> { 1, 2 }, { 3, 4, 10 }
arr.sum( x ) --> 20
arr.take( x, 2 ) --> { 1, 2 }
arr.take_every( x, 2 ) --> { 1, 3, 10 }
arr.unique( y ) --> { "a", "b", 1 }
arr.zip( x, y, {20, 30} ) --> { { 1, "a", 20 }, { 2, "b", 30 }, { 3, "b" }, { 4, 1 }, { 10 } }
arr.intersect( x, y ) --> { 1 }
arr.intersects( x, y ) --> true
arr.contains({ 1, 2, 3}, 3) --> true
arr.diff( x ) --> { 1, 1, 1, 6 }
arr.int( x ) --> { 1, 3, 6, 10, 20 }
arr.insert( x, y, 3 ) --> { 1, 2, { "a", "b", "b", 1 }, 3, 4, 10 }
inc = arr.newIncrementor( 10, 5 )
print( inc() ) --> 10
print( inc() ) --> 15
-- 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)
setmetatable(array, nil)
local str = mw.logObject( array )
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>