"ماڈیول:TableTools" کے نسخوں کے درمیان فرق
improved module formatting; improved isArray; added isArrayLike; fixed _deepCopy; and improved defaultKeySort, code by User:Alexiscoutinho |
Arsait (تبادلۂ خیال | شراکتیں) م 51 revisions imported ٹیگ: موبائل ترمیم موبائل ویب ترمیم |
||
(3 صارفین 4 کے درمیانی نسخے نہیں دکھائے گئے) | |||
سطر 38: | سطر 38: | ||
------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ||
function p.isNan(v) | function p.isNan(v) | ||
return type(v) == 'number' and | return type(v) == 'number' and v ~= v | ||
end | end | ||
سطر 64: | سطر 64: | ||
-- removed, but otherwise the array order is unchanged. | -- removed, but otherwise the array order is unchanged. | ||
------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ||
function p.removeDuplicates( | function p.removeDuplicates(arr) | ||
checkType('removeDuplicates', 1, | checkType('removeDuplicates', 1, arr, 'table') | ||
local isNan = p.isNan | local isNan = p.isNan | ||
local ret, exists = {}, {} | local ret, exists = {}, {} | ||
for _, v in ipairs( | for _, v in ipairs(arr) do | ||
if isNan(v) then | if isNan(v) then | ||
-- 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 | ||
سطر 337: | سطر 335: | ||
-- | -- | ||
-- Transposes the keys and values in an array. For example, {"a", "b", "c"} -> | -- Transposes the keys and values in an array. For example, {"a", "b", "c"} -> | ||
-- {a = 1, b = 2, c = 3}. | -- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to | ||
-- the index of the last duplicate) and NaN values are ignored. | |||
------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ||
function p.invert(arr) | function p.invert(arr) | ||
checkType("invert", 1, arr, "table") | checkType("invert", 1, arr, "table") | ||
local isNan = p.isNan | |||
local map = {} | local map = {} | ||
for i, v in ipairs(arr) do | for i, v in ipairs(arr) do | ||
map[v] = i | if not isNan(v) then | ||
map[v] = i | |||
end | |||
end | end | ||
سطر 355: | سطر 356: | ||
-- Creates a set from the array part of the table. Indexing the set by any of the | -- Creates a set from the array part of the table. Indexing the set by any of the | ||
-- values of the array returns true. For example, {"a", "b", "c"} -> | -- values of the array returns true. For example, {"a", "b", "c"} -> | ||
-- {a = true, b = true, c = true}. | -- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them | ||
-- never equal to any value (including other NaNs or even themselves). | |||
------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ||
function p.listToSet( | function p.listToSet(arr) | ||
checkType("listToSet", 1, | checkType("listToSet", 1, arr, "table") | ||
local isNan = p.isNan | |||
local set = {} | local set = {} | ||
for _, | for _, v in ipairs(arr) do | ||
set[ | if not isNan(v) then | ||
set[v] = true | |||
end | |||
end | end | ||
سطر 374: | سطر 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 | ||
سطر 405: | سطر 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 | ||
سطر 458: | سطر 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 |