Editing Module:ArrayGive feedback
Jump to navigation
Jump to search
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 1: | Line 1: | ||
-- <nowiki> awawa | |||
local libraryUtil = require('libraryUtil') | local libraryUtil = require('libraryUtil') | ||
local checkType = libraryUtil.checkType | local checkType = libraryUtil.checkType | ||
local checkTypeMulti = libraryUtil.checkTypeMulti | local checkTypeMulti = libraryUtil.checkTypeMulti | ||
local arr = {} | |||
setmetatable(arr, { | |||
__call = function (_, array) | |||
return arr.new(array) | |||
end | |||
}) | |||
if | |||
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 | end | ||
return res | |||
else | else | ||
return | return arr[k] | ||
end | end | ||
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 | ||
local | |||
} | |||
setmetatable( | |||
function | 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 = {} | local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs)) | ||
for i = 1, #lhs do | |||
for i = 1, | |||
res[i] = lhs[i] | res[i] = lhs[i] | ||
end | end | ||
for i = 1, | local l = #lhs | ||
res[ | for i = 1, #rhs do | ||
res[i + l] = rhs[i] | |||
end | end | ||
return | return res | ||
else | else | ||
return tostring(lhs) .. tostring(rhs) | return tostring(lhs) .. tostring(rhs) | ||
| Line 73: | Line 47: | ||
end | end | ||
function | function arr.__unm(array) | ||
return | return arr.map(array, function(x) return -x end) | ||
end | end | ||
local function mathTemplate(lhs, rhs, funName, fun) | |||
local function mathTemplate(lhs, rhs, funName | |||
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 = {} | local res = setmetatable({}, getmetatable(lhs) or getmetatable(rhs)) | ||
if type(lhs) == 'number' then | if type(lhs) == 'number' then | ||
for i = 1, | 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, | for i = 1, #lhs do | ||
res[i] = fun(lhs[i], rhs) | res[i] = fun(lhs[i], rhs) | ||
end | end | ||
else | else | ||
assert( | assert(#lhs == #rhs, string.format('Tables are not equal length (lhs=%d, rhs=%d)', #lhs, #rhs)) | ||
for i = 1, | for i = 1, #lhs do | ||
res[i] = fun(lhs[i], rhs[i]) | res[i] = fun(lhs[i], rhs[i]) | ||
end | end | ||
end | end | ||
return | return res | ||
end | end | ||
function | function arr.__add(lhs, rhs) | ||
return mathTemplate(lhs, rhs, '__add | return mathTemplate(lhs, rhs, '__add', function(x, y) return x + y end) | ||
end | end | ||
function | function arr.__sub(lhs, rhs) | ||
return mathTemplate(lhs, rhs, '__sub | return mathTemplate(lhs, rhs, '__sub', function(x, y) return x - y end) | ||
end | end | ||
function | function arr.__mul(lhs, rhs) | ||
return mathTemplate(lhs, rhs, '__mul | return mathTemplate(lhs, rhs, '__mul', function(x, y) return x * y end) | ||
end | end | ||
function | function arr.__div(lhs, rhs) | ||
return mathTemplate(lhs, rhs, '__div | return mathTemplate(lhs, rhs, '__div', function(x, y) return x / y end) | ||
end | end | ||
function | function arr.__pow(lhs, rhs) | ||
return mathTemplate(lhs, rhs, '__pow | return mathTemplate(lhs, rhs, '__pow', function(x, y) return x ^ y end) | ||
end | end | ||
function | function arr.__lt(lhs, rhs) | ||
if | 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 | return false | ||
end | end | ||
for i = 1, | for i = 1, #lhs do | ||
if lhs[i] ~= rhs[i] then | if lhs[i] ~= rhs[i] then | ||
return false | return false | ||
| Line 138: | Line 124: | ||
end | end | ||
function arr.all(array, fn) | |||
checkType('Module:Array.all', 1, array, 'table') | |||
checkType('Module:Array.all', 1, | |||
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 | ||
| Line 152: | Line 131: | ||
fn = function(item) return item == val end | fn = function(item) return item == val end | ||
end | end | ||
local i = 1 | |||
while array[i] ~= nil do | |||
if not fn( | 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 arr.any(array, fn) | |||
checkType('Module:Array.any', 1, array, 'table') | |||
checkType('Module:Array.any', 1, | |||
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 | ||
| Line 175: | Line 148: | ||
fn = function(item) return item == val end | fn = function(item) return item == val end | ||
end | end | ||
local i = 1 | |||
while array[i] ~= nil do | |||
if fn( | if fn(array[i], i) then | ||
return true | return true | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return false | return false | ||
end | end | ||
function arr.clean(array) | |||
checkType('Module:Array.clean', 1, array, 'table') | |||
for i = 1, #array do | |||
if type(array[i]) == 'table' then | |||
checkType('Module:Array.clean', 1, | arr.clean(array[i]) | ||
for i = 1, | |||
if type( | |||
end | end | ||
end | end | ||
setmetatable( | setmetatable(array, nil) | ||
return | return array | ||
end | 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) | |||
checkType('Module:Array. | for i = 1, #array do | ||
local j = elemMap[array[i]] | |||
if j then | |||
isFound[j] = true | |||
end | |||
end | end | ||
return arr.all(isFound, true) | |||
else | |||
return arr.any(array, function(item) return item == elem end) | |||
end | 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 | |||
function | |||
checkType('Module:Array.count', 1, | |||
if | |||
if type( | |||
local | |||
end | end | ||
local count = 0 | local count = 0 | ||
for i = 1, | for i = 1, #array do | ||
if | if fn(array[i]) then | ||
count = count + 1 | count = count + 1 | ||
end | end | ||
| Line 338: | Line 203: | ||
end | end | ||
function arr.diff(array, order) | |||
checkType('Module:Array.diff', 1, array, 'table') | |||
checkType('Module:Array.diff', 1, | |||
checkType('Module:Array.diff', 2, order, 'number', true) | checkType('Module:Array.diff', 2, order, 'number', true) | ||
local res = {} | local res = setmetatable({}, getmetatable(array)) | ||
for i = 1, | for i = 1, #array - 1 do | ||
res[i] = | res[i] = array[i+1] - array[i] | ||
end | end | ||
if order and order > 1 then | if order and order > 1 then | ||
return | return arr.diff(res, order - 1) | ||
end | end | ||
return | return res | ||
end | end | ||
function arr.each(array, fn) | |||
checkType('Module:Array.each', 1, array, 'table') | |||
checkType('Module:Array.each', 1, | |||
checkType('Module:Array.each', 2, fn, 'function') | checkType('Module:Array.each', 2, fn, 'function') | ||
local i = 1 | |||
fn( | while array[i] ~= nil do | ||
fn(array[i], i) | |||
i = i + 1 | |||
end | end | ||
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 | |||
checkType('Module:Array.filter', 1, | end | ||
local r = setmetatable({}, getmetatable(array)) | |||
local r = {} | local len = 0 | ||
local | local i = 1 | ||
while array[i] ~= nil do | |||
if fn( | if fn(array[i], i) then | ||
len = len + 1 | |||
r[ | r[len] = array[i] | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return | return r | ||
end | end | ||
function arr.find(array, fn, default) | |||
checkType('Module:Array.find', 1, array, 'table') | |||
checkType('Module:Array.find', 1, | |||
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 | local val = fn | ||
fn = function(item) return item == | fn = function(item) return item == val end | ||
end | end | ||
local i = 1 | |||
while array[i] ~= nil do | |||
if fn( | if fn(array[i], i) then | ||
return | return array[i], i | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return default | return default | ||
end | 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 | |||
checkType('Module:Array.find_index', 1, | |||
checkTypeMulti('Module:Array.find_index', 2, | |||
if type( | |||
local | |||
end | end | ||
local i = 1 | |||
while array[i] ~= nil do | |||
if | if fn(array[i], i) then | ||
return i | return i | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return default | return default | ||
end | 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 = {} | |||
checkType('Module:Array. | return setmetatable(obj, { | ||
__call = function() n = n + step return n end, | |||
__tostring = function() return n end, | |||
__index = function() return n end, | |||
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 | end | ||
function arr.int(array, start, stop) | |||
checkType('Module:Array.int', 1, array, 'table') | |||
checkType('Module:Array.int', 1, | |||
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 = {} | local res = setmetatable({}, getmetatable(array)) | ||
start = start or 1 | start = start or 1 | ||
stop = stop or | stop = stop or #array | ||
res[1] = | res[1] = array[start] | ||
for i = 1, stop - start do | for i = 1, stop - start do | ||
res[i+1] = res[i] + | res[i+1] = res[i] + array[start + i] | ||
end | end | ||
return | return res | ||
end | 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)) | |||
function | local len = 0 | ||
checkType('Module:Array.intersect', 1, | arr.each(array2, function(item) array2Elements[item] = true end) | ||
checkType('Module:Array.intersect', 2, | arr.each(array1, function(item) | ||
local | if array2Elements[item] then | ||
local res = {} | len = len + 1 | ||
local | res[len] = item | ||
if | |||
res[ | |||
end | end | ||
end) | end) | ||
return | return res | ||
end | end | ||
function arr.intersects(array1, array2) | |||
checkType('Module:Array.intersects', 1, array1, 'table') | |||
checkType('Module:Array.intersects', 2, array2, 'table') | |||
function | |||
checkType('Module:Array.intersects', 1, | |||
checkType('Module:Array.intersects', 2, | |||
local small = {} | local small = {} | ||
local large | local large | ||
if | if #array1 <= #array2 then | ||
arr.each(array1, function(item) small[item] = true end) | |||
large = | large = array2 | ||
else | else | ||
arr.each(array2, function(item) small[item] = true end) | |||
large = | large = array1 | ||
end | end | ||
return | return arr.any(large, function(item) return small[item] end) | ||
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', 1, | |||
checkType('Module:Array.insert', 4, unpackVal, 'boolean', true) | checkType('Module:Array.insert', 4, unpackVal, 'boolean', true) | ||
local len = #array | |||
index = index or (len + 1) | |||
local | |||
index = index or ( | |||
if | if type(val) == 'table' and unpackVal ~= false then | ||
local | local len2 = #val | ||
for i = 0, | for i = 0, len - index do | ||
array[len + len2 - i] = array[len - i] | |||
end | end | ||
for i = 0, | for i = 0, len2 - 1 do | ||
array[index + i] = val[i + 1] | |||
end | end | ||
else | else | ||
table.insert( | table.insert(array, index, val) | ||
end | end | ||
return | return array | ||
end | end | ||
function arr.map(array, fn) | |||
checkType('Module:Array.map', 1, array, 'table') | |||
checkType('Module:Array.map', 1, | |||
checkType('Module:Array.map', 2, fn, 'function') | checkType('Module:Array.map', 2, fn, 'function') | ||
local | local len = 0 | ||
local r = {} | local r = setmetatable({}, getmetatable(array)) | ||
local i = 1 | |||
local tmp = fn( | while array[i] ~= nil do | ||
local tmp = fn(array[i], i) | |||
if tmp ~= nil then | if tmp ~= nil then | ||
len = len + 1 | |||
r[ | r[len] = tmp | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return | return r | ||
end | end | ||
function arr.max_by(array, fn) | |||
checkType('Module:Array.max_by', 1, array, 'table') | |||
checkType('Module:Array.max_by', 1, | |||
checkType('Module:Array.max_by', 2, fn, 'function') | checkType('Module:Array.max_by', 2, fn, 'function') | ||
return unpack( | 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 | ||
| Line 586: | Line 394: | ||
end | end | ||
function arr.max(array) | |||
checkType('Module:Array.max', 1, array, 'table') | |||
local val, _, i = arr.max_by(array, function(x) return x end) | |||
checkType('Module:Array.max', 1, | |||
local val, _, i = | |||
return val, i | return val, i | ||
end | end | ||
function arr.min(array) | |||
checkType('Module:Array.min', 1, array, 'table') | |||
local val, _, i = arr.max_by(array, function(x) return -x end) | |||
checkType('Module:Array.min', 1, | |||
local val, _, i = | |||
return val, i | return val, i | ||
end | end | ||
function arr.new(array) | |||
array = array or {} | |||
for _, v in pairs(array) do | |||
for _, v in pairs( | |||
if type(v) == 'table' then | if type(v) == 'table' then | ||
arr.new(v) | |||
end | end | ||
end | end | ||
if getmetatable( | if getmetatable(array) == nil then | ||
setmetatable( | setmetatable(array, arr) | ||
end | end | ||
return | return array | ||
end | end | ||
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 | local array = setmetatable({}, arr) | ||
local len = 0 | local len = 0 | ||
if not stop then | if not stop then | ||
| Line 704: | Line 433: | ||
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 | |||
end | end | ||
return | return array | ||
end | end | ||
function arr.reduce(array, fn, accumulator) | |||
checkType('Module:Array.reduce', 1, array, 'table') | |||
checkType('Module:Array.reduce', 1, | |||
checkType('Module:Array.reduce', 2, fn, 'function') | checkType('Module:Array.reduce', 2, fn, 'function') | ||
local acc = accumulator | local acc = accumulator | ||
local | local i = 1 | ||
if acc == nil then | if acc == nil then | ||
acc = | acc = array[1] | ||
i = 2 | |||
end | end | ||
while array[i] ~= nil do | |||
acc = fn( | acc = fn(array[i], acc, i) | ||
i = i + 1 | |||
end | end | ||
return acc | return acc | ||
end | 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} | |||
checkType('Module:Array.reject', 1, | |||
checkTypeMulti('Module:Array.reject', 2, | |||
if type( | |||
end | end | ||
local r = {} | local r = setmetatable({}, getmetatable(array)) | ||
local | local len = 0 | ||
if type( | if type(fn) == 'function' then | ||
local i = 1 | |||
if not | while array[i] ~= nil do | ||
if not fn(array[i], i) then | |||
r[ | len = len + 1 | ||
r[len] = array[i] | |||
end | end | ||
i = i + 1 | |||
end | end | ||
else | else | ||
local rejectMap = {} | local rejectMap = {} | ||
arr.each(fn, function(item) rejectMap[item] = true end) | |||
local i = 1 | |||
if not rejectMap[ | while array[i] ~= nil do | ||
if not rejectMap[array[i]] then | |||
r[ | len = len + 1 | ||
r[len] = array[i] | |||
end | end | ||
i = i + 1 | |||
end | end | ||
end | end | ||
return | return r | ||
end | end | ||
function arr.rep(val, n) | |||
function | |||
checkType('Module:Array.rep', 2, n, 'number') | checkType('Module:Array.rep', 2, n, 'number') | ||
local r = {} | local r = setmetatable({}, arr) | ||
for i = 1, n do | for i = 1, n do | ||
r[i] = val | r[i] = val | ||
end | end | ||
return | return r | ||
end | end | ||
function arr.scan(array, fn, accumulator) | |||
checkType('Module:Array.scan', 1, array, 'table') | |||
checkType('Module:Array.scan', 1, | |||
checkType('Module:Array.scan', 2, fn, 'function') | checkType('Module:Array.scan', 2, fn, 'function') | ||
local acc = accumulator | local acc = accumulator | ||
local r = {} | local r = setmetatable({}, getmetatable(array)) | ||
local i = 1 | |||
while array[i] ~= nil do | |||
if i == 1 and not accumulator then | if i == 1 and not accumulator then | ||
acc = | acc = array[i] | ||
else | else | ||
acc = fn( | acc = fn(array[i], acc) | ||
end | end | ||
r[i] = acc | r[i] = acc | ||
i = i + 1 | |||
end | end | ||
return | return r | ||
end | end | ||
function arr.slice(array, start, finish) | |||
checkType('Module:Array.slice', 1, array, 'table') | |||
checkType('Module:Array.slice', 1, | |||
checkType('Module:Array.slice', 2, start, 'number', true) | checkType('Module:Array.slice', 2, start, 'number', true) | ||
checkType('Module:Array.slice', 3, | checkType('Module:Array.slice', 3, finish, 'number', true) | ||
start = start or | start = start or 1 | ||
if start < 0 | finish = finish or #array | ||
if start < 0 and finish == nil then | |||
finish = #array + start | |||
start = 1 | start = 1 | ||
elseif start < 0 then | |||
start = #array + start | |||
end | end | ||
if | if finish < 0 then | ||
finish = #array + finish | |||
end | end | ||
local r = {} | local r = setmetatable({}, getmetatable(array)) | ||
local len = 0 | local len = 0 | ||
for i = start, | for i = start, finish do | ||
len = len + 1 | len = len + 1 | ||
r[len] = | r[len] = array[i] | ||
end | end | ||
return | return r | ||
end | 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]) | |||
checkType('Module:Array.split', 1, | |||
checkType('Module:Array.split', 2, | |||
local x = {} | |||
local y = {} | |||
for i = 1, | |||
table.insert(i <= | |||
end | end | ||
return | return x, y | ||
end | end | ||
function arr.sum(array) | |||
checkType('Module:Array.sum', 1, array, 'table') | |||
checkType('Module:Array.sum', 1, | |||
local res = 0 | local res = 0 | ||
for i = 1, | for i = 1, #array do | ||
res = res + | res = res + array[i] | ||
end | end | ||
return res | return res | ||
end | end | ||
function arr.take(array, count, offset) | |||
checkType('Module:Array.take', 1, array, 'table') | |||
checkType('Module:Array.take', 1, | |||
checkType('Module:Array.take', 2, count, 'number') | checkType('Module:Array.take', 2, count, 'number') | ||
checkType('Module:Array.take', 3, | checkType('Module:Array.take', 3, offset, 'number', true) | ||
local x = {} | local x = setmetatable({}, getmetatable(array)) | ||
for i = offset or 1, #array do | |||
if i <= count then | |||
table.insert(x, array[i]) | |||
end | |||
end | end | ||
return | return x | ||
end | end | ||
function arr.take_every(array, n, offset) | |||
checkType('Module:Array.take_every', 1, array, 'table') | |||
checkType('Module:Array.take_every', 1, | |||
checkType('Module:Array.take_every', 2, n, 'number') | checkType('Module:Array.take_every', 2, n, 'number') | ||
checkType('Module:Array.take_every', 3, | checkType('Module:Array.take_every', 3, offset, 'number', true) | ||
local r = setmetatable({}, getmetatable(array)) | |||
local len = 0 | |||
local i = offset or 1 | |||
local | while array[i] ~= nil do | ||
local | len = len + 1 | ||
local | r[len] = array[i] | ||
i = i + n | |||
r[ | |||
end | end | ||
return | return r | ||
end | end | ||
function arr.unique(array, fn) | |||
checkType('Module:Array.unique', 1, array, 'table') | |||
checkType('Module:Array.unique', 1, | |||
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 = {} | local r = setmetatable({}, getmetatable(array)) | ||
local | local len = 0 | ||
local hash = {} | local hash = {} | ||
local i = 1 | |||
local id = fn( | while array[i] ~= nil do | ||
local id = fn(array[i]) | |||
if not hash[id] then | if not hash[id] then | ||
len = len + 1 | |||
r[ | r[len] = array[i] | ||
hash[id] = true | hash[id] = true | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return | return r | ||
end | 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} | |||
checkType('Module:Array. | |||
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] | |||
if type( | |||
for i = 1, | |||
end | end | ||
else | else | ||
for i = 1, #indexes do | |||
array[indexes[i]] = values | |||
end | end | ||
end | end | ||
return array | |||
end | 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]) | |||
checkType('Module:Array. | |||
for | |||
end | end | ||
table.insert(r, q) | |||
end | end | ||
return r | |||
return | |||
end | end | ||
return | return arr | ||
-- </nowiki> | |||