Comparing tables in lua where keys are tables

I need to compare if the two tables are equal - as in the same content. Both tables have tables as keys.

For instance:

t1 = {{1,1},{2,2}}
t2 = {{1,1},{2,2}}
t3 = {{1,1},{2,2},{3,3}}

t1 and t2 should be equal, but t1 and t3 should not be equal.

+4
source share
2 answers

My solution is not absolute (doesn't like keys), but should work with the nested tables that you specify. My concept is recursive and simple:

Take a record from each input, make sure that they: are of type, both are tables, and both tables are the same length. If these three things are true, you can now 1: 1 recursively compare two tables. If the types do not match or the tables have different lengths, this is an automatic failure.

function compare (one, two)

    if type(one) == type(two) then
        if type(one) == "table" then
            if #one == #two then

                -- If both types are the same, both are tables and 
                -- the tables are the same size, recurse through each
                -- table entry.
                for loop=1, #one do
                    if compare (one[loop], two[loop]) == false then
                        return false
                    end
                end 

                -- All table contents match
                return true
            end
        else
            -- Values are not tables but matching types. Compare
            -- them and return if they match
            return one == two
        end
    end
    return false
end

do
    t1 = {{1,1},{2,2}}
    t2 = {{1,1},{2,2}}
    t3 = {{1,1},{2,2},{3,3}}

    print (string.format(
        "t1 == t2 : %s", 
        tostring(compare (t1,t2))))

    print (string.format(
        "t1 == t3 : %s", 
        tostring(compare (t1,t3))))
end

Conclusion:

t1 == t2 : true
t1 == t3 : false
0
source

- Lua. , . , .

, A B . A , A B, .

( PIL) a b:

function basicSerialize (o)
    if type(o) == "number" then
      return tostring(o)
    else   -- assume it is a string
      return string.format("%q", o)
    end
end

function save (name, value, saved, output)
    saved = saved or {}       -- initial value
    output = output or {}     -- initial value
    if type(value) == "number" or type(value) == "string" then
        table.insert (output, name .. " = " .. basicSerialize(value))
    elseif type(value) == "table" then
        if saved[value] then    -- value already saved?
            table.insert (output, name .. " = " .. saved[value])  -- use its previous name
        else
            saved [value] = name   -- save name for next time
            table.insert (output, name .. " = {}")     -- create a new table
            for k,v in pairs(value) do      -- save its fields
                local fieldname = string.format("%s[%s]", name, basicSerialize(k))
                save (fieldname, v, saved, output)
            end
        end
    else
        error("cannot save a " .. type(value))
    end
    return output
end

function compareSerializedTable (t1, t2)
    if (#t1 ~= #t2) then
        return false
    end

    for i = #t1, 1, -1 do
        local line = t1 [i]
        for k, comp in ipairs (t2) do
            if (line == comp) then
                table.remove (t1, i)
                table.remove (t2, k)
                break
            end
        end
    end

    return (#t1 == 0 and #t2 == 0)
end

t1 = {{1,1},{2,2}}
t2 = {{1,1},{2,2}}
t3 = {{1,1},{2,2},{3,3}}

o1 = save ('t', t1)
o2 = save ('t', t2)
o3 = save ('t', t3)

print (compareSerializedTable (o1, o2)) --true
print (compareSerializedTable (o1, o3)) --false
0

Source: https://habr.com/ru/post/1687500/


All Articles