lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> 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
added and removed:

----------------------
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