Module:TableTools: Difference between revisions
Update from sandbox per request
Nazarzadeh (talk | contribs) m (1 revision imported) |
(Update from sandbox per request) |
||
Line 72: | Line 72: | ||
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence. | -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. | ||
ret[#ret + 1] = v | ret[#ret + 1] = v | ||
elseif not exists[v] then | |||
ret[#ret + 1] = v | |||
exists[v] = true | |||
end | end | ||
end | end | ||
Line 380: | Line 378: | ||
------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ||
local function _deepCopy(orig, includeMetatable, already_seen) | local function _deepCopy(orig, includeMetatable, already_seen) | ||
-- | if type(orig) ~= "table" then | ||
return orig | |||
end | |||
-- already_seen stores copies of tables indexed by the original table. | |||
local copy = already_seen[orig] | local copy = already_seen[orig] | ||
if copy ~= nil then | if copy ~= nil then | ||
return copy | return copy | ||
end | end | ||
copy = {} | |||
already_seen[orig] = copy -- memoize before any recursion, to avoid infinite loops | |||
for orig_key, orig_value in pairs(orig) do | |||
copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen) | |||
end | |||
if includeMetatable then | |||
local mt = getmetatable(orig) | |||
if mt ~= nil then | |||
setmetatable(copy, _deepCopy(mt, true, already_seen)) | |||
end | end | ||
end | end | ||
return copy | return copy | ||
end | end | ||
Line 411: | Line 407: | ||
function p.deepCopy(orig, noMetatable, already_seen) | function p.deepCopy(orig, noMetatable, already_seen) | ||
checkType("deepCopy", 3, already_seen, "table", true) | checkType("deepCopy", 3, already_seen, "table", true) | ||
return _deepCopy(orig, not noMetatable, already_seen) | return _deepCopy(orig, not noMetatable, already_seen or {}) | ||
end | end | ||
Line 464: | Line 460: | ||
-- inArray | -- inArray | ||
-- | -- | ||
-- Returns true if | -- Returns true if searchElement is a member of the array, and false otherwise. | ||
-- Equivalent to JavaScript array.includes(searchElement) or | |||
-- array.includes(searchElement, fromIndex), except fromIndex is 1 indexed | |||
------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ||
function p.inArray( | function p.inArray(array, searchElement, fromIndex) | ||
checkType("inArray", 1, | checkType("inArray", 1, array, "table") | ||
-- if | -- if searchElement is nil, error? | ||
for _, v in ipairs( | fromIndex = tonumber(fromIndex) | ||
if v == | if fromIndex then | ||
if (fromIndex < 0) then | |||
fromIndex = #array + fromIndex + 1 | |||
end | |||
if fromIndex < 1 then fromIndex = 1 end | |||
for _, v in ipairs({unpack(array, fromIndex)}) do | |||
if v == searchElement then | |||
return true | |||
end | |||
end | |||
else | |||
for _, v in pairs(array) do | |||
if v == searchElement then | |||
return true | |||
end | |||
end | end | ||
end | end | ||
return false | return false | ||
end | |||
------------------------------------------------------------------------------------ | |||
-- merge | |||
-- | |||
-- Given the arrays, returns an array containing the elements of each input array | |||
-- in sequence. | |||
------------------------------------------------------------------------------------ | |||
function p.merge(...) | |||
local arrays = {...} | |||
local ret = {} | |||
for i, arr in ipairs(arrays) do | |||
checkType('merge', i, arr, 'table') | |||
for _, v in ipairs(arr) do | |||
ret[#ret + 1] = v | |||
end | |||
end | |||
return ret | |||
end | |||
------------------------------------------------------------------------------------ | |||
-- extend | |||
-- | |||
-- Extends the first array in place by appending all elements from the second | |||
-- array. | |||
------------------------------------------------------------------------------------ | |||
function p.extend(arr1, arr2) | |||
checkType('extend', 1, arr1, 'table') | |||
checkType('extend', 2, arr2, 'table') | |||
for _, v in ipairs(arr2) do | |||
arr1[#arr1 + 1] = v | |||
end | |||
end | end | ||
return p | return p |