• Subject: Re: Table compare
• From: "Vaughan McAlley" <ockegheim@...>
• Date: Wed, 31 Dec 2008 00:05:10 +1100

```> You have two table traversals here, that kind of defeats the table.len() check purpose.

If table.len returns false there is no need to do the traversals.
Otherwise it's pretty unavoidable.

This code uses metatables to calculate table lengths as items are

----------------------
local uniqueKey = {}
local tableLength = uniqueKey -- for naming clarity

local metaT = {
__newindex = function(t, k, v)
local realTable = ShowRealTable(t)
if v == nil then
if realTable[k] ~= nil then
realTable[tableLength] = realTable[tableLength] - 1
realTable[k] = nil
end
else
if realTable[k] == nil then
realTable[tableLength] = realTable[tableLength] + 1
end
realTable[k] = v
end
end ,
__index = function(t, k)
return ShowRealTable(t)[k]
end
}

function CreateTable()
local intermediateTable = {}
local realTable = {}
intermediateTable[uniqueKey] = realTable
realTable[tableLength] = 0
setmetatable(intermediateTable, metaT)
return intermediateTable
end

-- instead of pairs(t), use pairs(ShowRealTable(t))
function ShowRealTable(t)
return t[uniqueKey]
end

function ShowLength(t)
return ShowRealTable(t)[tableLength]
end

function TableCompare(a, b)
if ShowLength(a) ~= ShowLength(b) then
return false
end
local a1 = ShowRealTable(a)
local b1 = ShowRealTable(b)
for key, value in pairs(a1) do
if b1[key] ~= value then
return false
end
end
for key, value in pairs(b1) do
if a1[key] ~= value then
return false
end
end
return true
end

local t1 = CreateTable()
local t2 = CreateTable()
t1.x = 45
t1[34] = "blah"
t1[false] = TableCompare

t2[34] = "blah"
t2[false] = TableCompare

t1.x = nil

print(ShowLength(t1), TableCompare(t1, t2)) --> 2, true

------------------

It could be possible using metatables to have a two-dimensional array
of differences between tables built up as tables are created and
modified. That would save the traversals when comparing but would add
a memory and perhaps performance burden.

Vaughan

```