是否有检查表是否包含值的方法?我有自己的(幼稚)功能,但我想知道是否存在“正式”的东西?或者更高效的东西...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
顺便说一句,我使用这个函数的主要原因是使用表作为集合,即没有重复元素。还有其他我可以使用的东西吗?
答案 0 :(得分:109)
您可以将值作为表的键。例如:
function addToSet(set, key)
set[key] = true
end
function removeFromSet(set, key)
set[key] = nil
end
function setContains(set, key)
return set[key] ~= nil
end
有一个功能更全面的示例here。
答案 1 :(得分:24)
鉴于您的代表性,您的功能与可以完成的效率一样高。当然,正如其他人所指出的那样(并且在Lua之前的语言中实践过),您真正问题的解决方案是改变代表性。如果有表并且需要集,则可以使用set元素作为键并将true
作为值,将表转换为集合。 +1来兼任。
答案 2 :(得分:2)
我想不出另一种比较值的方法,但是如果你使用set的元素作为键,你可以将值设置为除nil之外的任何值。然后,您无需搜索整个表格即可快速查找。
答案 3 :(得分:2)
我知道这是一个老帖子,但我想为后代添加一些内容。 处理问题的简单方法是创建另一个值为key的表。
即。你有2个具有相同值的表,一个指向一个方向,一个指向另一个。
function addValue(key, value)
if (value == nil) then
removeKey(key)
return
end
_primaryTable.key = value
_secodaryTable.value = key
end
function removeKey(key)
local value = _primaryTable.key
if (value == nil) then
return
end
_primaryTable.key = nil
_secondaryTable.value = nil
end
function getValue(key)
return _primaryTable.key
end
function containsValue(value)
return _secondaryTable.value ~= nil
end
然后,您可以查询新表以查看它是否具有键“元素”。这可以防止需要遍历另一个表的每个值。
如果事实证明您实际上不能使用'element'作为键,因为它不是一个字符串,例如,然后在其上添加校验和或'toString',然后将其用作键
你为什么要这样做?如果您的表非常大,迭代每个元素的时间量将会非常大,从而使您无法经常执行此操作。额外的内存开销相对较小,因为它将存储2个指向同一对象的指针,而不是相同对象的2个副本。 如果你的表非常小,那么它就更不重要了,事实上,迭代甚至可能比另一个地图查找更快。
但问题的措辞强烈暗示你有大量的事项需要处理。
答案 4 :(得分:1)
-- in some helper module
function utils_Set(list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
-- your table here
long_table = { "v1", "v2", "v1000"}
-- Consult some value
_set = utils_Set(long_table)
if _set["v1"] then print("yes!") end