Module:Array: Difference between revisions

Jump to navigation Jump to search
osrsw>Shoyrukon
m Protected "Module:Enum" ([Edit=Only allow autoconfirmed users] (indefinite) [Move=Only allow autoconfirmed users] (indefinite))
osrsw>CephHunter
Sync with rsw
Line 3: Line 3:
local checkType = libraryUtil.checkType
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
local checkTypeMulti = libraryUtil.checkTypeMulti
local p = {}
local arr = {}


function p.all(enum, fn, clone)
setmetatable(arr, {
checkType('Module:Enum.all', 1, enum, 'table')
__call = function (_, array)
checkType('Module:Enum.all', 2, fn, 'function', true)
return arr.new(array)
checkType('Module:Enum.all', 3, clone, 'boolean', true)
end
if clone then enum = mw.clone(enum) end
})
fn = fn or function(item) return item end
 
for _, item in ipairs(enum) do
function arr.__index(t, k)
if not fn(item) then
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 = mw.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:Enum.' .. funName, 1, lhs, {'number', 'table'})
checkTypeMulti('Module:Enum.' .. 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:Enum.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
return false
end
end
i = i + 1
end
end
return true
return true
end
end


function p.any(enum, fn, clone)
function arr.any(array, fn)
checkType('Module:Enum.any', 1, enum, 'table')
checkType('Module:Enum.any', 1, array, 'table')
checkType('Module:Enum.any', 2, fn, 'function', true)
if fn == nil then fn = function(item) return item end end
checkType('Module:Enum.any', 3, clone, 'boolean', true)
if type(fn) ~= 'function' then
if clone then enum = mw.clone(enum) end
local val = fn
fn = fn or function(item) return item end
fn = function(item) return item == val end
for _, item in ipairs(enum) do
end
if fn(item) then
local i = 1
while array[i] ~= nil do
if fn(array[i], i) then
return true
return true
end
end
i = i + 1
end
end
return false
return false
end
end


function p.contains(enum, elem, clone)
function arr.clean(array)
checkType('Module:Enum.contains', 1, enum, 'table')
checkType('Module:Enum.clean', 1, array, 'table')
checkType('Module:Enum.contains', 3, clone, 'boolean', true)
for i = 1, #array do
if clone then enum = mw.clone(enum); elem = mw.clone(elem) end
if type(array[i]) == 'table' then
return p.any(enum, function(item) return item == elem end)
arr.clean(array[i])
end
end
setmetatable(array, nil)
return array
end
 
function arr.contains(array, elem, useElemTableContent)
checkType('Module:Enum.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:Enum.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
end


function p.each(enum, fn, clone)
function arr.diff(array, order)
checkType('Module:Enum.each', 1, enum, 'table')
checkType('Module:Enum.diff', 1, array, 'table')
checkType('Module:Enum.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:Enum.each', 1, array, 'table')
checkType('Module:Enum.each', 2, fn, 'function')
checkType('Module:Enum.each', 2, fn, 'function')
checkType('Module:Enum.each', 3, clone, 'boolean', true)
local i = 1
if clone then enum = mw.clone(enum) end
while array[i] ~= nil do
for _, item in ipairs(enum) do
fn(array[i], i)
fn(item)
i = i + 1
end
end
end
end


function p.filter(enum, fn, clone)
function arr.filter(array, fn)
checkType('Module:Enum.filter', 1, enum, 'table')
checkType('Module:Enum.filter', 1, array, 'table')
checkType('Module:Enum.filter', 2, fn, 'function', true)
if fn == nil then fn = function(item) return item end end
checkType('Module:Enum.filter', 3, clone, 'boolean', true)
if type(fn) ~= 'function' then
if clone then enum = mw.clone(enum) end
local val = fn
fn = fn or function(item) return item end
fn = function(item) return item == val end
local r = {}
end
for _, item in ipairs(enum) do
local r = setmetatable({}, getmetatable(array))
if fn(item) then
local len = 0
table.insert(r, item)
local i = 1
while array[i] ~= nil do
if fn(array[i], i) then
len = len + 1
r[len] = array[i]
end
end
i = i + 1
end
end
return r
return r
end
end


function p.find(enum, fn, default, clone)
function arr.find(array, fn, default)
checkType('Module:Enum.find', 1, enum, 'table')
checkType('Module:Enum.find', 1, array, 'table')
checkType('Module:Enum.find', 2, fn, 'function')
checkTypeMulti('Module:Enum.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
checkType('Module:Enum.find', 4, clone, 'boolean', true)
if type(fn) ~= 'function' then
if clone then enum = mw.clone(enum); default = mw.clone(default) end
local val = fn
for _, item in ipairs(enum) do
fn = function(item) return item == val end
if fn(item) then
end
return item
local i = 1
while array[i] ~= nil do
if fn(array[i], i) then
return array[i], i
end
end
i = i + 1
end
end
return default
return default
end
end


function p.find_index(enum, fn, default, clone)
function arr.find_index(array, fn, default)
checkType('Module:Enum.find_index', 1, enum, 'table')
checkType('Module:Enum.find_index', 1, array, 'table')
checkType('Module:Enum.find_index', 2, fn, 'function')
checkTypeMulti('Module:Enum.find_index', 2, fn, {'function', 'table', 'number', 'boolean'})
checkType('Module:Enum.find_index', 4, clone, 'boolean', true)
if type(fn) ~= 'function' then
if clone then enum = mw.clone(enum); default = mw.clone(default) end
local val = fn
for index, item in ipairs(enum) do
fn = function(item) return item == val end
if fn(item) then
end
return index
local i = 1
while array[i] ~= nil do
if fn(array[i], i) then
return i
end
end
i = i + 1
end
end
return default
return default
end
end


function p.newIncrementor(start, step)
function arr.newIncrementor(start, step)
checkType('Module:Enum.newIncrementor', 1, start, 'number', true)
checkType('Module:Enum.newIncrementor', 1, start, 'number', true)
checkType('Module:Enum.newIncrementor', 2, step, 'number', true)
checkType('Module:Enum.newIncrementor', 2, step, 'number', true)
Line 112: Line 301:
end
end


function p.intersect(enum1, enum2, clone)
function arr.int(array, start, stop)
checkType('Module:Enum.intersect', 1, enum1, 'table')
checkType('Module:Enum.int', 1, array, 'table')
checkType('Module:Enum.intersect', 2, enum2, 'table')
checkType('Module:Enum.int', 2, start, 'number', true)
checkType('Module:Enum.intersect', 3, clone, 'boolean', true)
checkType('Module:Enum.int', 3, stop, 'number', true)
if clone then enum1 = mw.clone(enum1); enum2 = mw.clone(enum2) end
local res = setmetatable({}, getmetatable(array))
local enum2Elements = {}
start = start or 1
local res = {}
stop = stop or #array
p.each(enum2, function(item) enum2Elements[item] = true end)
res[1] = array[start]
p.each(enum1, function(item)
for i = 1, stop - start do
if enum2Elements[item] then
res[i+1] = res[i] + array[start + i]
table.insert(res, item)
end
return res
end
 
function arr.intersect(array1, array2)
checkType('Module:Enum.intersect', 1, array1, 'table')
checkType('Module:Enum.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
end)
end)
Line 128: Line 331:
end
end


function p.intersects(enum1, enum2, clone)
function arr.intersects(array1, array2)
checkType('Module:Enum.intersects', 1, enum1, 'table')
checkType('Module:Enum.intersects', 1, array1, 'table')
checkType('Module:Enum.intersects', 2, enum2, 'table')
checkType('Module:Enum.intersects', 2, array2, 'table')
checkType('Module:Enum.intersects', 3, clone, 'boolean', true)
local small = {}
if clone then enum1 = mw.clone(enum1); enum2 = mw.clone(enum2) end
local large
return p.any(enum1, function(item1) return p.any(enum2, function(item2) return item1==item2 end) end)
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
end


function p.insert(enum1, enum2, index, clone)
function arr.insert(array, val, index, unpackVal)
checkType('Module:Enum.insert', 1, enum1, 'table')
checkType('Module:Enum.insert', 1, array, 'table')
checkType('Module:Enum.insert', 2, enum2, 'table')
checkType('Module:Enum.insert', 3, index, 'number', true)
checkType('Module:Enum.insert', 3, index, 'number', true)
checkType('Module:Enum.insert', 4, clone, 'boolean', true)
checkType('Module:Enum.insert', 4, unpackVal, 'boolean', true)
if clone then enum1 = mw.clone(enum1); enum2 = mw.clone(enum2) end
local len = #array
local len1 = #enum1
index = index or (len + 1)
local len2 = #enum2
index = index or (len1 + 1)
local res = {}


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


return res
return array
end
end


function p.map(enum, fn, clone)
function arr.map(array, fn)
checkType('Module:Enum.map', 1, enum, 'table')
checkType('Module:Enum.map', 1, array, 'table')
checkType('Module:Enum.map', 2, fn, 'function')
checkType('Module:Enum.map', 2, fn, 'function')
checkType('Module:Enum.map', 3, clone, 'boolean', true)
local len = 0
if clone then enum = mw.clone(enum) end
local r = setmetatable({}, getmetatable(array))
local r = {}
local i = 1
for _, item in ipairs(enum) do
while array[i] ~= nil do
local temp = fn(item) -- Only use first returned item
local tmp = fn(array[i], i)
table.insert(r, temp)
if tmp ~= nil then
len = len + 1
r[len] = tmp
end
i = i + 1
end
end
return r
return r
end
end


function p.max_by(enum, fn, clone)
function arr.max_by(array, fn)
checkType('Module:Enum.max_by', 1, enum, 'table')
checkType('Module:Enum.max_by', 1, array, 'table')
checkType('Module:Enum.max_by', 2, fn, 'function')
checkType('Module:Enum.max_by', 2, fn, 'function')
checkType('Module:Enum.max_by', 3, clone, 'boolean', true)
return unpack(arr.reduce(array, function(new, old, i)
if clone then enum = mw.clone(enum) end
return unpack(p.reduce(enum, function(new, old)
local y = fn(new)
local y = fn(new)
return y > old[2] and {new, y} or old
return y > old[2] and {new, y, i} or old
end, {0, 0}))
end, {nil, -math.huge}))
end
 
function arr.max(array)
checkType('Module:Enum.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:Enum.min', 1, array, 'table')
local val, _, i = arr.max_by(array, function(x) return -x end)
return val, i
end
end


function p.range(start, stop, step)
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:Enum.range', 1, start, 'number')
checkType('Module:Enum.range', 1, start, 'number')
checkType('Module:Enum.range', 2, stop, 'number', true)
checkType('Module:Enum.range', 2, stop, 'number', true)
checkType('Module:Enum.range', 3, step, 'number', true)
checkType('Module:Enum.range', 3, step, 'number', true)
local array = {}
local array = setmetatable({}, arr)
local len = 0
if not stop then
if not stop then
stop = start
stop = start
start = 1
start = 1
end
end
local j = 1
for i = start, stop, step or 1 do
for i = start, stop, step or 1 do
array[j] = i
len = len + 1
j = j + 1
array[len] = i
end
end
return array
return array
end
end


function p.reduce(enum, fn, accumulator, clone)
function arr.reduce(array, fn, accumulator)
checkType('Module:Enum.reduce', 1, enum, 'table')
checkType('Module:Enum.reduce', 1, array, 'table')
checkType('Module:Enum.reduce', 2, fn, 'function')
checkType('Module:Enum.reduce', 2, fn, 'function')
checkType('Module:Enum.reduce', 4, clone, 'boolean', true)
if clone then enum = mw.clone(enum); accumulator = mw.clone(accumulator) end
local acc = accumulator
local acc = accumulator
for index, item in ipairs(enum) do
local i = 1
if index == 1 and not accumulator then
if acc == nil then
acc = item
acc = array[1]
else
i = 2
acc = fn(item, acc)
end
end
while array[i] ~= nil do
acc = fn(array[i], acc, i)
i = i + 1
end
end
return acc
return acc
end
end


function p.reject(enum, fn, clone)
function arr.reject(array, fn)
checkType('Module:Enum.reject', 1, enum, 'table')
checkType('Module:Enum.reject', 1, array, 'table')
checkTypeMulti('Module:Enum.reject', 2, fn, {'function', 'table', 'nil'})
checkTypeMulti('Module:Enum.reject', 2, fn, {'function', 'table', 'number', 'boolean'})
checkType('Module:Enum.reject', 3, clone, 'boolean', true)
if fn == nil then fn = function(item) return item end end
if clone then enum = mw.clone(enum) end
if type(fn) ~= 'function' and type(fn) ~= 'table' then
fn = fn or function(item) return item end
fn = {fn}
local r = {}
end
local r = setmetatable({}, getmetatable(array))
local len = 0
if type(fn) == 'function' then
if type(fn) == 'function' then
for index, item in ipairs(enum) do
local i = 1
if not fn(item, index) then
while array[i] ~= nil do
table.insert(r, item)
if not fn(array[i], i) then
len = len + 1
r[len] = array[i]
end
end
i = i + 1
end
end
else
else
local rejectMap = {}
local rejectMap = {}
for _, item in ipairs(fn) do
arr.each(fn, function(item) rejectMap[item] = true end)
rejectMap[item] = true
local i = 1
end
while array[i] ~= nil do
for _, item in ipairs(enum) do
if not rejectMap[array[i]] then
if not rejectMap[item] then
len = len + 1
table.insert(r, item)
r[len] = array[i]
end
end
i = i + 1
end
end
end
end
Line 244: Line 487:
end
end


function p.scan(enum, fn, accumulator, clone)
function arr.rep(val, n)
checkType('Module:Enum.scan', 1, enum, 'table')
checkType('Module:Enum.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:Enum.scan', 1, array, 'table')
checkType('Module:Enum.scan', 2, fn, 'function')
checkType('Module:Enum.scan', 2, fn, 'function')
checkType('Module:Enum.scan', 4, clone, 'boolean', true)
if clone then enum = mw.clone(enum); accumulator = mw.clone(accumulator) end
local acc = accumulator
local acc = accumulator
local r = {}
local r = setmetatable({}, getmetatable(array))
for index, item in ipairs(enum) do
local i = 1
if index == 1 and not accumulator then
while array[i] ~= nil do
acc = item
if i == 1 and not accumulator then
acc = array[i]
else
else
acc = fn(item, acc)
acc = fn(array[i], acc)
end
end
table.insert(r, acc)
r[i] = acc
i = i + 1
end
end
return r
return r
end
end


function p.slice(enum, start, finish, clone)
function arr.slice(array, start, finish)
checkType('Module:Enum.slice', 1, enum, 'table')
checkType('Module:Enum.slice', 1, array, 'table')
checkType('Module:Enum.slice', 2, start, 'number', true)
checkType('Module:Enum.slice', 2, start, 'number', true)
checkType('Module:Enum.slice', 3, finish, 'number', true)
checkType('Module:Enum.slice', 3, finish, 'number', true)
checkType('Module:Enum.slice', 4, clone, 'boolean', true)
if clone then enum = mw.clone(enum) end
start = start or 1
start = start or 1
finish = finish or #enum
finish = finish or #array
local r = {}
if start < 0 and finish == nil then
for index, item in ipairs(enum) do
finish = #array + start
if index >= start and index <= finish then
start = 1
table.insert(r, item)
elseif start < 0 then
end
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
end
return r
return r
end
end


function p.split(enum, count, clone)
function arr.split(array, count)
checkType('Module:Enum.split', 1, enum, 'table')
checkType('Module:Enum.split', 1, array, 'table')
checkType('Module:Enum.split', 2, count, 'number')
checkType('Module:Enum.split', 2, count, 'number')
checkType('Module:Enum.split', 3, clone, 'boolean', true)
local x = setmetatable({}, getmetatable(array))
if clone then enum = mw.clone(enum) end
local y = setmetatable({}, getmetatable(array))
if #enum < count then
for i = 1, #array do
return enum, {}
table.insert(i <= count and x or y, array[i])
elseif count < 1 then
return {}, enum
end
 
local x = {}
local y = {}
 
for i = 1, #enum do
table.insert(
i <= count and x or y,
enum[i]
)
end
end
return x, y
return x, y
end
end


function p.sum(enum, clone)
function arr.sum(array)
checkType('Module:Enum.sum', 1, enum, 'table')
checkType('Module:Enum.sum', 1, array, 'table')
checkType('Module:Enum.sum', 2, clone, 'boolean', true)
local res = 0
if clone then enum = mw.clone(enum) end
for i = 1, #array do
return p.reduce(enum, function(x, y) return x + y end)
res = res + array[i]
end
return res
end
end


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


function p.take_every(enum, n, clone)
function arr.take_every(array, n, offset)
checkType('Module:Enum.take_every', 1, enum, 'table')
checkType('Module:Enum.take_every', 1, array, 'table')
checkType('Module:Enum.take_every', 2, n, 'number')
checkType('Module:Enum.take_every', 2, n, 'number')
checkType('Module:Enum.take_every', 3, clone, 'boolean', true)
checkType('Module:Enum.take_every', 3, offset, 'number', true)
if clone then enum = mw.clone(enum) end
local r = setmetatable({}, getmetatable(array))
local r = {}
local len = 0
for index, item in ipairs(enum) do
local i = offset or 1
if (index - 1) % n == 0 then
while array[i] ~= nil do
table.insert(r, item)
len = len + 1
end
r[len] = array[i]
i = i + n
end
end
return r
return r
end
end


function p.take_from(enum, index, count)
function arr.unique(array, fn)
checkType('Module:Enum.take_from', 1, enum, 'table')
checkType('Module:Enum.unique', 1, array, 'table')
checkType('Module:Enum.take_from', 2, index, 'number')
checkType('Module:Enum.take_from', 3, count, 'number')
local x, _ = p.split(p.reject(enum,
function(item, idx)
return idx < index
end
), count)
return x
end
 
function p.unique(enum, fn, clone)
checkType('Module:Enum.unique', 1, enum, 'table')
checkType('Module:Enum.unique', 2, fn, 'function', true)
checkType('Module:Enum.unique', 2, fn, 'function', true)
checkType('Module:Enum.unique', 3, clone, 'boolean', true)
if clone then enum = mw.clone(enum) end
fn = fn or function(item) return item end
fn = fn or function(item) return item end
local r = {}
local r = setmetatable({}, getmetatable(array))
local len = 0
local hash = {}
local hash = {}
for _, item in ipairs(enum) do
local i = 1
local id = fn(item)
while array[i] ~= nil do
local id = fn(array[i])
if not hash[id] then
if not hash[id] then
table.insert(r, item)
len = len + 1
r[len] = array[i]
hash[id] = true
hash[id] = true
end
end
i = i + 1
end
end
return r
return r
end
end


function p.zip(enums, clone)
function arr.update(array, indexes, values)
checkType('Module:Enum.zip', 1, enums, 'table')
checkType('Module:Enum.update', 1, array, 'table')
checkType('Module:Enum.zip', 2, clone, 'boolean', true)
checkTypeMulti('Module:Enum.update', 2, indexes, {'table', 'number'})
if clone then enums = mw.clone(enums) end
if type(indexes) == 'number' then
local r = {}
indexes = {indexes}
local _, longest = p.max_by(enums, function(enum) return #enum end)
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:Enum.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
for i = 1, longest do
local q = {}
local q = {}
for j = 1, #enums do
for j = 1, #arrays do
table.insert(q, enums[j][i])
table.insert(q, arrays[j][i])
end
end
table.insert(r, q)
table.insert(r, q)
Line 378: Line 640:
end
end


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