是否有一种简单的方法可以创建类似字典的集合,即
e.g。之后
t = createCustomTable()
k1 = {'a','b','c'}
k2 = {'a','b','c'}
t[k1] = true
t[k2]
应评估为true
t
本身也应该以相同的方式用作关键字。
如果没有
,有没有办法做到这一点k1
和k2
转换为字符串? (这就是我目前正在做的事情。)答案 0 :(得分:4)
将两个表序列化为字符串是解决方案Roberto Ierusalimschy(Lua的首席架构师)建议按照Lua第二版编程中的内容进行索引。
如果所有关键表都是字符串数组(没有嵌入的空值),则可以使用table.concat(t,'\0')
快速完成此操作。 (显然,如果你想要与索引无关的身份,你的表将需要sorted。)
答案 1 :(得分:3)
如果要用作键的表是固定的并且其内容不会更改,则可以在{em> newindex 元方法中为t
按需构建SHA2摘要,并使用摘要作为真正的关键。摘要将缓存在由真实表索引的另一个表中。
答案 2 :(得分:1)
您可以在两个表的元表中实现和设置__eq方法。
k1 = {'a','b','c'}
k2 = {'a','b','c'}
mt1={__eq=function(a,b)
for k,v in pairs(a) do
if b[k]~=v then return false end
end
for k,v in pairs(b) do
if a[k]~=v then return false end
end
return true
end
}
setmetatable(k1,mt1)
setmetatable(k2,mt1)
assert(k1==k2,"Table comparison failed")
function newDict(orig)
if orig then
return orig
else
local mt2={}
local lookup ={} -- lookup table as upvalue to the metamethods
mt2.__newindex = function(t,k,v) -- Registering a new table
if type(k)~="table" then return end
if v then -- v ~= false
local found
for idx,val in pairs(lookup) do
if k==val then
found=1
break
end -- If already seen, skip.
end
if not found then
lookup[#lookup+1]=k -- not seen before, add
end
else -- v == false or nil
local to_erase
for idx,val in pairs(lookup) do -- Assume there is only one match in the dict.
if k==val then
lookup[k]=nil
break
end --don't continue after this, next will be confused.
end
end
end
mt2.__index = function(t,k) -- looking up a table
for idx,val in pairs(lookup) do
if k==val then
return true
end
end
return false
end
return setmetatable({},mt2)
end
end
t1 = newDict()
t2 = newDict()
k1={1,2,3}
k2={"a"}
k3={"z","d","f"}
k1b={1,2,3}
k2b={"a"}
k3b={"z","d","f"}
setmetatable(k1,mt1)
setmetatable(k2,mt1)
setmetatable(k3,mt1)
setmetatable(k1b,mt1)
setmetatable(k2b,mt1)
setmetatable(k3b,mt1)
-- Test multiple entries in 1 dict
t1[k1]=true
t1[k2]=true
assert(t1[k1b],"t1[k1b] did not return true")
assert(t1[k2b],"t1[k2b] did not return true")
-- Test confusion between 2 dicts
t2[k3]=true
assert(not t1[k3b],"t1[k3b] did return true")
assert(not t2[k1b],"t2[k1b] did return true")
比较可以更快地实现,因为现在常见的条目被检查两次,但是你明白了。
我无法评论性能,因为它确实使用了metatable查找,并且需要遍历每个比较或赋值的所有表,但是因为您不想散列表或将它们转换为字符串(aka序列化他们)这是唯一的方法。如果我是你,我会认真考虑检查表的序列化,而不是上面的方法。
答案 3 :(得分:0)
This(“键是引用”部分)表示键是对象的引用,因此使用与示例中相同的表将不起作用。我认为你目前的做法可能是最好的方式,但我可能是错的。
答案 4 :(得分:0)
如果您可以使用库依赖项,则可以使用类似Penlight的内容,它似乎提供了集http://penlight.luaforge.net/#T10。