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 2: | Line 2: | ||
local checkType = libraryUtil.checkType | local checkType = libraryUtil.checkType | ||
local checkTypeMulti = libraryUtil.checkTypeMulti | local checkTypeMulti = libraryUtil.checkTypeMulti | ||
---@class Array | ---@class Array | ||
| Line 45: | Line 14: | ||
---@operator pow(number|number[]|Array): Array | ---@operator pow(number|number[]|Array): Array | ||
local Array = { | local Array = { | ||
pop = table.remove | pop = table.remove | ||
} | } | ||
Array.__index = Array | Array.__index = Array | ||
| Line 56: | Line 24: | ||
end | end | ||
}) | }) | ||
-- function Array.__tostring(arr) | |||
-- -- local dumpObject = require('Module:Logger').dumpObject | |||
-- require 'log' | |||
-- local dumpObject = dumpObject | |||
-- local mt = getmetatable(arr) | |||
-- setmetatable(arr, nil) | |||
-- local str = dumpObject(arr, {clean=true, collapseLimit=100}) | |||
-- setmetatable(arr, mt) | |||
-- return str | |||
-- end | |||
function Array.__concat(lhs, rhs) | function Array.__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 = {} | ||
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 setmetatable(res, getmetatable(lhs) or getmetatable(rhs)) | return setmetatable(res, getmetatable(lhs) or getmetatable(rhs)) | ||
| Line 89: | Line 68: | ||
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('Elementwise %s failed because arrays have different sizes (left: %d, right: %d)', opName, #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 | ||
| Line 127: | Line 106: | ||
function Array.__eq(lhs, rhs) | function Array.__eq(lhs, rhs) | ||
if | 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 152: | Line 131: | ||
fn = function(item) return item == val end | fn = function(item) return item == val end | ||
end | end | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
---@diagnostic disable-next-line: redundant-parameter | ---@diagnostic disable-next-line: redundant-parameter | ||
if not fn(arr[i], i) then | if not fn(arr[i], i) then | ||
return false | return false | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return true | return true | ||
| Line 175: | Line 156: | ||
fn = function(item) return item == val end | fn = function(item) return item == val end | ||
end | end | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
---@diagnostic disable-next-line: redundant-parameter | ---@diagnostic disable-next-line: redundant-parameter | ||
if fn(arr[i], i) then | if fn(arr[i], i) then | ||
return true | return true | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return false | return false | ||
| Line 189: | Line 172: | ||
function Array.clean(arr) | function Array.clean(arr) | ||
checkType('Module:Array.clean', 1, arr, 'table') | checkType('Module:Array.clean', 1, arr, 'table') | ||
for i = 1, | for i = 1, #arr do | ||
if type(arr[i]) == 'table' then | if type(arr[i]) == 'table' then | ||
Array.clean(arr[i]) | Array.clean(arr[i]) | ||
| Line 207: | Line 190: | ||
checkType('Module:Array.clone', 2, deep, 'boolean', true) | checkType('Module:Array.clone', 2, deep, 'boolean', true) | ||
local res = {} | local res = {} | ||
for i = 1, | for i = 1, #arr do | ||
if deep == true and type(arr[i]) == 'table' then | if deep == true and type(arr[i]) == 'table' then | ||
res[i] = Array.clone(arr[i], true) | res[i] = Array.clone(arr[i], true) | ||
| Line 223: | Line 206: | ||
function Array.contains(arr, val) | function Array.contains(arr, val) | ||
checkType('Module:Array.contains', 1, arr, 'table') | checkType('Module:Array.contains', 1, arr, 'table') | ||
for i = 1, | for i = 1, #arr do | ||
if arr[i] == val then | if arr[i] == val then | ||
return true | return true | ||
| Line 239: | Line 222: | ||
checkType('Module:Array.containsAny', 2, t, 'table') | checkType('Module:Array.containsAny', 2, t, 'table') | ||
local lookupTbl = {} | local lookupTbl = {} | ||
for i = 1, | for i = 1, #t do | ||
lookupTbl[t[i]] = true | lookupTbl[t[i]] = true | ||
end | end | ||
for i = 1, | for i = 1, #arr do | ||
if lookupTbl[arr[i]] then | if lookupTbl[arr[i]] then | ||
return true | return true | ||
| Line 258: | Line 241: | ||
checkType('Module:Array.containsAll', 2, t, 'table') | checkType('Module:Array.containsAll', 2, t, 'table') | ||
local lookupTbl = {} | local lookupTbl = {} | ||
local l = #t | |||
local trueCount = 0 | local trueCount = 0 | ||
for i = 1, l do | for i = 1, l do | ||
lookupTbl[t[i]] = false | lookupTbl[t[i]] = false | ||
end | end | ||
for i = 1, | for i = 1, #arr do | ||
if lookupTbl[arr[i]] == false then | if lookupTbl[arr[i]] == false then | ||
lookupTbl[arr[i]] = true | lookupTbl[arr[i]] = true | ||
| Line 284: | Line 267: | ||
checkType('Module:Array.convolve', 2, y, 'table') | checkType('Module:Array.convolve', 2, y, 'table') | ||
local z = {} | local z = {} | ||
local xLen, yLen = | local xLen, yLen = #x, #y | ||
for j = 1, (xLen + yLen - 1) do | for j = 1, (xLen + yLen - 1) do | ||
local sum = 0 | local sum = 0 | ||
| Line 330: | Line 313: | ||
end | end | ||
local count = 0 | local count = 0 | ||
for i = 1, | for i = 1, #arr do | ||
if val(arr[i]) then | if val(arr[i]) then | ||
count = count + 1 | count = count + 1 | ||
| Line 347: | Line 330: | ||
checkType('Module:Array.diff', 2, order, 'number', true) | checkType('Module:Array.diff', 2, order, 'number', true) | ||
local res = {} | local res = {} | ||
for i = 1, | for i = 1, #arr - 1 do | ||
res[i] = arr[i+1] - arr[i] | res[i] = arr[i+1] - arr[i] | ||
end | end | ||
| Line 362: | Line 345: | ||
checkType('Module:Array.each', 1, arr, 'table') | checkType('Module:Array.each', 1, arr, 'table') | ||
checkType('Module:Array.each', 2, fn, 'function') | checkType('Module:Array.each', 2, fn, 'function') | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
fn(arr[i], i) | fn(arr[i], i) | ||
i = i + 1 | |||
end | end | ||
end | end | ||
| Line 376: | Line 361: | ||
checkType('Module:Array.filter', 2, fn, 'function') | checkType('Module:Array.filter', 2, fn, 'function') | ||
local r = {} | local r = {} | ||
local | local len = 0 | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
if fn(arr[i], i) then | if fn(arr[i], i) then | ||
len = len + 1 | |||
r[ | r[len] = arr[i] | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return setmetatable(r, getmetatable(arr)) | return setmetatable(r, getmetatable(arr)) | ||
| Line 399: | Line 386: | ||
fn = function(item) return item == _val end | fn = function(item) return item == _val end | ||
end | end | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
---@diagnostic disable-next-line: redundant-parameter | ---@diagnostic disable-next-line: redundant-parameter | ||
if fn(arr[i], i) then | if fn(arr[i], i) then | ||
return arr[i], i | return arr[i], i | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return default, nil | return default, nil | ||
| Line 420: | Line 409: | ||
val = function(item) return item == _val end | val = function(item) return item == _val end | ||
end | end | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
---@diagnostic disable-next-line: redundant-parameter | ---@diagnostic disable-next-line: redundant-parameter | ||
if val(arr[i], i) then | if val(arr[i], i) then | ||
return i | return i | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return default | return default | ||
| Line 441: | Line 432: | ||
end | end | ||
local res = {} | local res = {} | ||
for i = 1, | for i = 1, #indexes do | ||
res[i] = arr[indexes[i]] | res[i] = arr[indexes[i]] | ||
end | end | ||
| Line 459: | Line 450: | ||
local res = {} | local res = {} | ||
start = start or 1 | start = start or 1 | ||
stop = stop or | stop = stop or #arr | ||
res[1] = arr[start] | res[1] = arr[start] | ||
for i = 1, stop - start do | for i = 1, stop - start do | ||
| Line 477: | Line 468: | ||
local arr2Elements = {} | local arr2Elements = {} | ||
local res = {} | local res = {} | ||
local | local len = 0 | ||
Array.each(arr2, function(item) arr2Elements[item] = true end) | Array.each(arr2, function(item) arr2Elements[item] = true end) | ||
Array.each(arr1, function(item) | Array.each(arr1, function(item) | ||
if arr2Elements[item] then | if arr2Elements[item] then | ||
len = len + 1 | |||
res[ | res[len] = item | ||
end | end | ||
end) | end) | ||
| Line 497: | Line 488: | ||
local small = {} | local small = {} | ||
local large | local large | ||
if | if #arr1 <= #arr2 then | ||
Array.each(arr1, function(item) small[item] = true end) | Array.each(arr1, function(item) small[item] = true end) | ||
large = arr2 | large = arr2 | ||
| Line 522: | Line 513: | ||
unpackVal, index = index, nil | unpackVal, index = index, nil | ||
end | end | ||
local | local len = #arr | ||
index = index or ( | index = index or (len + 1) | ||
local mt = getmetatable(arr) | local mt = getmetatable(arr) | ||
setmetatable(arr, nil) | setmetatable(arr, nil) | ||
if | if type(val) == 'table' and unpackVal then | ||
local | local len2 = #val | ||
for i = 0, | for i = 0, len - index do | ||
arr[ | arr[len + len2 - i] = arr[len - i] | ||
end | end | ||
for i = 0, | for i = 0, len2 - 1 do | ||
arr[index + i] = val[i + 1] | arr[index + i] = val[i + 1] | ||
end | end | ||
| Line 549: | Line 540: | ||
checkType('Module:Array.last', 1, arr, 'table') | checkType('Module:Array.last', 1, arr, 'table') | ||
checkType('Module:Array.last', 2, offset, 'number', true) | checkType('Module:Array.last', 2, offset, 'number', true) | ||
return arr[ | return arr[#arr + offset] | ||
end | end | ||
| Line 560: | Line 551: | ||
checkType('Module:Array.map', 1, arr, 'table') | checkType('Module:Array.map', 1, arr, 'table') | ||
checkType('Module:Array.map', 2, fn, 'function') | checkType('Module:Array.map', 2, fn, 'function') | ||
local | local len = 0 | ||
local r = {} | local r = {} | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
local tmp = fn(arr[i], i) | local tmp = fn(arr[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 setmetatable(r, getmetatable(arr)) | return setmetatable(r, getmetatable(arr)) | ||
| Line 673: | Line 666: | ||
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 | __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) | ||
| Line 726: | Line 719: | ||
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 = arr[1] | acc = arr[1] | ||
i = 2 | |||
end | end | ||
while arr[i] ~= nil do | |||
acc = fn(arr[i], acc, i) | acc = fn(arr[i], acc, i) | ||
i = i + 1 | |||
end | end | ||
return acc | return acc | ||
| Line 754: | Line 748: | ||
end | end | ||
local r = {} | local r = {} | ||
local | local len = 0 | ||
if type(val) == 'function' then | if type(val) == 'function' then | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
if not val(arr[i], i) then | if not val(arr[i], i) then | ||
len = len + 1 | |||
r[ | r[len] = arr[i] | ||
end | end | ||
i = i + 1 | |||
end | end | ||
else | else | ||
local rejectMap = {} | local rejectMap = {} | ||
Array.each(val --[[@as any[] ]], function(item) rejectMap[item] = true end) | Array.each(val --[[@as any[] ]], function(item) rejectMap[item] = true end) | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
if not rejectMap[arr[i]] then | if not rejectMap[arr[i]] then | ||
len = len + 1 | |||
r[ | r[len] = arr[i] | ||
end | end | ||
i = i + 1 | |||
end | end | ||
end | end | ||
| Line 807: | Line 805: | ||
local acc = accumulator | local acc = accumulator | ||
local r = {} | local r = {} | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
if i == 1 and not accumulator then | if i == 1 and not accumulator then | ||
acc = arr[i] | acc = arr[i] | ||
| Line 814: | Line 813: | ||
end | end | ||
r[i] = acc | r[i] = acc | ||
i = i + 1 | |||
end | end | ||
return setmetatable(r, getmetatable(arr)) | return setmetatable(r, getmetatable(arr)) | ||
| Line 837: | Line 837: | ||
end | end | ||
if type(values) == 'table' then | if type(values) == 'table' then | ||
assert( | assert(#indexes == #values, string.format("Module:Array.set: 'indexes' and 'values' arrays are not equal length (#indexes = %d, #values = %d)", #indexes, #values)) | ||
for i = 1, | for i = 1, #indexes do | ||
arr[indexes[i]] = values[i] | arr[indexes[i]] = values[i] | ||
end | end | ||
else | else | ||
for i = 1, | for i = 1, #indexes do | ||
arr[indexes[i]] = values | arr[indexes[i]] = values | ||
end | end | ||
| Line 860: | Line 860: | ||
checkType('Module:Array.slice', 2, start, 'number', true) | checkType('Module:Array.slice', 2, start, 'number', true) | ||
checkType('Module:Array.slice', 3, stop, 'number', true) | checkType('Module:Array.slice', 3, stop, 'number', true) | ||
start = start or | start = start or #arr | ||
if start < 0 then | if start < 0 then | ||
start = | start = #arr + start | ||
end | end | ||
if stop == nil then | if stop == nil then | ||
| Line 869: | Line 869: | ||
end | end | ||
if stop < 0 then | if stop < 0 then | ||
stop = | stop = #arr + stop | ||
end | end | ||
local r = {} | local r = {} | ||
| Line 891: | Line 891: | ||
local x = {} | local x = {} | ||
local y = {} | local y = {} | ||
for i = 1, | for i = 1, #arr do | ||
table.insert(i <= index and x or y, arr[i]) | table.insert(i <= index and x or y, arr[i]) | ||
end | end | ||
| Line 903: | Line 903: | ||
checkType('Module:Array.sum', 1, arr, 'table') | checkType('Module:Array.sum', 1, arr, 'table') | ||
local res = 0 | local res = 0 | ||
for i = 1, | for i = 1, #arr do | ||
res = res + arr[i] | res = res + arr[i] | ||
end | end | ||
| Line 921: | Line 921: | ||
local x = {} | local x = {} | ||
start = start or 1 | start = start or 1 | ||
for i = start, math.min( | for i = start, math.min(#arr, count + start - 1) do | ||
table.insert(x, arr[i]) | table.insert(x, arr[i]) | ||
end | end | ||
| Line 931: | Line 931: | ||
---local t = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } | ---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 ) --> x = { 1, 3, 5, 7, 9 } | ||
---local x = arr.take_every( t, 2, 3 ) --> x = { 3, 5 | ---local x = arr.take_every( t, 2, 3 ) --> x = { 1, 3, 5 } | ||
---local x = arr.take_every( t, 2, 3, 2 ) --> x = { | ---local x = arr.take_every( t, 2, 3, 2 ) --> x = { 2, 4, 6 } | ||
--- ``` | --- ``` | ||
---@generic T: any[] | ---@generic T: any[] | ||
| Line 945: | Line 945: | ||
checkType('Module:Array.take_every', 3, start, 'number', true) | checkType('Module:Array.take_every', 3, start, 'number', true) | ||
checkType('Module:Array.take_every', 4, count, 'number', true) | checkType('Module:Array.take_every', 4, count, 'number', true) | ||
count = count or | count = count or #arr | ||
local r = {} | local r = {} | ||
local | local len = 0 | ||
local i = start or 1 | |||
while arr[i] ~= nil and len < count do | |||
r[ | len = len + 1 | ||
r[len] = arr[i] | |||
i = i + n | |||
end | end | ||
return setmetatable(r, getmetatable(arr)) | return setmetatable(r, getmetatable(arr)) | ||
| Line 967: | Line 967: | ||
fn = fn or function(item) return item end | fn = fn or function(item) return item end | ||
local r = {} | local r = {} | ||
local | local len = 0 | ||
local hash = {} | local hash = {} | ||
local i = 1 | |||
while arr[i] ~= nil do | |||
local id = fn(arr[i]) | local id = fn(arr[i]) | ||
if not hash[id] then | if not hash[id] then | ||
len = len + 1 | |||
r[ | r[len] = arr[i] | ||
hash[id] = true | hash[id] = true | ||
end | end | ||
i = i + 1 | |||
end | end | ||
return setmetatable(r, getmetatable(arr)) | return setmetatable(r, getmetatable(arr)) | ||
| Line 992: | Line 994: | ||
checkType('Module:Array.zip', 1, arrs[1], 'table') | checkType('Module:Array.zip', 1, arrs[1], 'table') | ||
local r = {} | local r = {} | ||
local _, longest = Array.max_by(arrs, function(arr) return | local _, longest = Array.max_by(arrs, function(arr) return #arr end) | ||
for i = 1, longest do | for i = 1, longest do | ||
local q = {} | local q = {} | ||
for j = 1, | for j = 1, #arrs do | ||
table.insert(q, arrs[j][i]) | table.insert(q, arrs[j][i]) | ||
end | end | ||
| Line 1,012: | Line 1,014: | ||
if type(k) == 'table' then | if type(k) == 'table' then | ||
local res = {} | local res = {} | ||
for i = 1, | for i = 1, #k do | ||
res[i] = t[k[i]] | res[i] = t[k[i]] | ||
end | end | ||
| Line 1,024: | Line 1,026: | ||
if type(k) == 'table' then | if type(k) == 'table' then | ||
if type(v) == 'table' then | if type(v) == 'table' then | ||
for i = 1, | for i = 1, #k do | ||
t[k[i]] = v[i] | t[k[i]] = v[i] | ||
end | end | ||
else | else | ||
for i = 1, | for i = 1, #k do | ||
t[k[i]] = v | t[k[i]] = v | ||
end | end | ||