Module:TableTools: Difference between revisions

From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
add isNan function, shallowClone function and removeDuplicates function, fix up valueIntersection function to work properly for NaNs
(clone tn rather than returning an altered tn)
(add isNan function, shallowClone function and removeDuplicates function, fix up valueIntersection function to work properly for NaNs)
Line 25:
-- isPositiveInteger
--
-- This function returns true if the given numbervalue is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
Line 31:
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(numv)
if type(numv) == 'number' and numv >= 1 and floor(numv) == numv and numv < infinity then
return true
else
return false
end
end
 
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
 
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
 
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if val == nanisNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
 
Line 167 ⟶ 228:
function p.valueIntersection(...)
local lim = select('#', ...)
if lim ==< 02 then
error("nolim arguments.. ' argument' .. (lim == 1 and '' or 's') .. " passed to 'valueIntersectionintersection' (minimum is 2)", 2)
end
local isNan = p.isNan
local vals, ret = {}, {}
local isSameTable = true -- Tracks table equality.
local tableTemp -- Used to store the table from the previous loop so that we can check table equality.
for i = 1, lim do
local t = select(i, ...)
checkType('valueIntersection', i, t, 'table')
if tableTemp and t ~= tableTemp then
isSameTable = false
end
tableTemp = t
for k, v in pairs(t) do
-- NaNs are never equal to any other value, so they can't be in the intersection.
if type(v) == 'number' and tostring(v) == '-nan' then
v = nan -- NaNWhich cannotis belucky, aas tablethey key,also socan't usebe a proxytable variablekeys.
if not isNan(v) then
local valCount = vals[v] or 0
vals[v] = valCount + 1
end
local valCount = vals[v] or 0
vals[v] = valCount + 1
end
end
if isSameTable then
-- If all the tables are equal, then the intersection is that table (including NaNs).
-- All we need to do is convert it to an array and remove duplicate values.
for k, v in pairs(tableTemp) do
ret[#ret + 1] = v
end
return p.removeDuplicates(ret)
end
for val, count in pairs(vals) do
if count == lim then
if val == nan then
-- This ensures that we output a NaN when we had one as input, although
-- they may have been generated in a completely different way.
val = 0/0
end
ret[#ret + 1] = val
end
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu