Comparison By Value

lua-users home
wiki

Difference (from revision 3 to current revision) (minor diff, author diff)

Changed: 1c1
The function 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), with the same value will have the same hash.
The function 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.

Changed: 3c3
{{{!Lua
{{{!Lua

Changed: 5,13c5,13
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
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

Changed: 17,24c17,24
return setmetatable(t, {
__index = function(t, k)
return t[gethash(k)]
end,
__newindex = function(t, k, v)
rawset(t, gethash(k), v)
end,
})
return setmetatable(t, {
__index = function(t, k)
return t[gethash(k)]
end,
__newindex = function(t, k, v)
rawset(t, gethash(k), v)
end,
})

Added: 26a27,28
-- example usage


Removed: 31d32


Removed: 33d33


Removed: 37d36


Removed: 39d37


Added: 42a41,70
}}}

Here's an alternate implementation --DavidManura

{{{!Lua
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")

The function 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")

Here's an alternate implementation --DavidManura

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

RecentChanges · preferences
edit · history
Last edited September 5, 2008 1:22 am GMT (diff)