lua-users home
lua-l archive

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

I've faced this in luaSub; the solution being to produce a string describing the "fingerprint" of the table. Using sort to make sure they are identical, even if string keys are used.

-- str= table_id(tbl)
-- Returns a unique ID for the assert template table; subsequent calls must
-- give the exact same string.
-- [1..N]:  tbl / assert_func / true
-- [str]:   tbl / assert_func
local function table_id( t )
    local sort= {}  -- parts collected: "<1..N>=..." "<string>=..."

    -- Collect IDs for each key
    for k,v in pairs(t) do
        local vt= type(v)
        local s
        if vt=="table" then
            s= "{"..table_id(v).."}"

        elseif vt=="function" then
-- tostring(func) gives "function: 0xNNNNN"; the "function: " is -- unnecessary for us but it does not really matter (except for -- the cached memory strings taking up some bytes). Remove it anyways.
            s= string.gsub( tostring(v), "function: ", "", 1 )
            assert( v==true )
            s= "..."    -- true means "..." as the last param
        sort[#sort+1]= k.."="..s

    table.sort( sort )

    return table.concat( sort, "," )

Matthew Armstrong kirjoitti 11.3.2008 kello 4:48:

Normally, if I index a table with another table as a key, the keying is done by the table key's instance (essentially, its address). What I want is for the keying to be defined by the table key's _contents_ (the structure of the table).

For instance, I want to do something like:

t = makeASpecialTable()
t[{a=1, b=2}] = 42
assert(t[{a=1, b=2}] == 42)

One way to solve this problem is to serialize the table key into string. This works, but probably isn't all that efficient ... or maybe making the generated string smaller would help?

Has anyone dealt with this problem before?