lua-users home
lua-l archive

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


G.H. <code933k <at> gmail.com> writes:

> 
> You are all very right. 
> Thanks for pointing out the weaknesses of such approach.
> 
> (Feel free to ignore the rest of this message)
> 
> Now I wonder if there is a way in Lua scripts for comparing
> table values so that loops can be minimized by using an
> "internal" function, instead of looping as usual. Specially
> if both tables are quite large and different just at the very end.
> 
> I am used to for loops comparing tables at i and n - i positions
> at the same time, but it's probably prone to be slower in some
> cases [...] And surely not useful for "dictionary" alike tables.
> 
> Greetings.
> 
> --
> Mario
> 
> 


I have an untested solution which deal with the general problem were tables 
points to tables and table can have metatable.
Not fast but general.


--------------- compareTable (depth)
--returns true tables are equal
--------- false tables are different
--------- nil cannot compare

function compareTable_(t1, t2, called)
    if t1 == t2 then return true end
    if type(t1) == 'table' and type(t2) == 'table' then
        -- allready compared
        dump(called)
        if called[t1] == t2 then return true end
        -- getmetatable may create an error this justifies the pcall
        -- cannot compare table with meta table they could self modified
        -- return nil  
        if getmetatable(t1) or getmetatable(t2) then return end
        called[t1] = t2 -- this one is being compared
        for k, v in pairs(t1)  do
            if v ~= t2[k] then
                if type(v) == 'table' and type(t2[k]) == 'table' then
                    local result = compareTable_(t2[k], v, called)
                    if not result then return result end
                else 
                    return false
                end
            end
        end 
        return true
    else
        return false
    end
end

function compareTable(t1, t2)
--returns true tables are equal
--------- false tables are different
--------- nil cannot compare
--------- equal scalars will also return true
    if t1 == t2 then return true end
    local r1, r2 = pcall(compareTable_, t1, t2, {})
    if r1 and r2 then 
        r1, r2 = pcall(compareTable_, t2, t1, {})
    end
    if r1 then return r2 end
end

Andre