Comparison By Value |
|
hashed
below adds a metatable to the given table t
, so that any write or read in the table will actually use a hash of the key instead of the key itself. This allows simulating the comparison of keys by values. To achieve that, make sure that two objects (table or userdata) that should have the same value have the same hash.
local function gethash(k) local hash = k local mt = getmetatable(k) local __hash = mt and mt.__hash if type(__hash)=='function' then hash = __hash(k) elseif type(__hash)~='nil' then hash = __hash end return hash end function hashed(t) return setmetatable(t, { __index = function(t, k) return t[gethash(k)] end, __newindex = function(t, k, v) rawset(t, gethash(k), v) end, }) end -- example usage local t1 = setmetatable({}, {__hash = 42}) local t2 = setmetatable({}, {__hash = 42}) local t = {} t[t1] = "foo" assert(t[t2]==nil) t = hashed({}) t[t1] = "foo" assert(t[t2]=="foo") t[t2] = "bar" assert(t[t1]=="bar")
local mt = { __mode = 'kv', __index = function(t,k) return k end } local function newkeymap(t) return setmetatable(t or {}, mt) end function hashed(t, keymap) return setmetatable(t, { __index = function(t, k) return rawget(t, keymap[k]) end, __newindex = function(t, k, v) rawset(t, keymap[k], v) end, }) end -- example usage local t = {} t.BAR = "foo" assert(t.bar==nil) local keymap = newkeymap { BAR = 'bar' } t = hashed({}, keymap) t.bar = "foo" assert(t.BAR=="foo") t.BAR = "bar" assert(t.bar=="bar")