如何检查表是不是包含Lua中的元素?
Posted
技术标签:
【中文标题】如何检查表是不是包含Lua中的元素?【英文标题】:How to check if a table contains an element in Lua?如何检查表是否包含Lua中的元素? 【发布时间】:2011-01-17 22:54:32 【问题描述】:有没有一种方法可以检查一个表是否包含一个值?我有自己的(天真的)功能,但我想知道是否存在“官方”的东西?或者更高效的方法...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
顺便说一句,我使用这个函数的主要原因是使用表格作为集合,即没有重复的元素。还有什么我可以用的吗?
【问题讨论】:
_,符号是什么意思? 这只是一个名为_
的“垃圾”变量。 pairs()
返回key, value
,但在这个例子中我只需要这个值。这是一种约定(在“Lua 编程”lua.org/pil/index.html 一书中采用)使用这个_
变量来存储你不需要的东西。
我在 Python 和 javascript 中也看到了命名“垃圾”变量_
的约定。
【参考方案1】:
您可以将值作为表的键。例如:
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。
【讨论】:
一位匿名用户建议对您的代码进行以下修复:如果具有指定键的集合中的值为 FALSE,则函数 setContains() 将返回 false,尽管表中有一个项目具有指定的键。 “return set[key] ~= nil”这一行修复了这个错误。 也许还有function keysOfSet(set) local ret= for k,_ in pairs(set) do ret[#ret+1]=k end return ret end
【参考方案2】:
鉴于您的表述,您的功能已尽其所能。当然,正如其他人所指出的(以及在 Lua 之前的语言中所实践的),您真正问题的解决方案是改变表示。当您有表格并且想要集合时,您可以使用 set 元素作为键并使用 true
作为值将表格转换为集合。 +1 给 interjay。
【讨论】:
“官方”方法可能会在 C 中执行此操作,这样会更快。但如果只在 lua 中完成,如你所说,这是可能的最有效的方法!【参考方案3】:我知道这是一篇旧帖子,但我想为后代添加一些内容。 处理您遇到的问题的简单方法是创建另一个表,对键值。
即。您有 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
然后您可以查询新表以查看它是否具有键“元素”。这避免了遍历另一个表的每个值的需要。
如果事实证明您实际上不能将“元素”用作键,例如因为它不是字符串,那么例如在其上添加校验和或tostring
,然后将其用作键.
为什么要这样做?如果您的表非常大,则遍历每个元素的时间会很长,从而使您无法经常这样做。额外的内存开销相对较小,因为它将存储 2 个指向同一个对象的指针,而不是同一个对象的 2 个副本。 如果您的表非常小,那么它的影响会小得多,事实上,迭代甚至可能比另一个地图查找更快。
然而,问题的措辞强烈暗示您有大量的项目需要处理。
【讨论】:
一个很好的解释,但并没有真正为讨论添加任何内容。编辑 interjay 的答案可能是一个更好的主意。 另外,在这段代码中,'.key' 应替换为 '[key]'(与 'value' 相同)【参考方案4】:我想不出另一种比较值的方法,但是如果您使用集合的元素作为键,您可以将值设置为 nil 以外的任何值。然后您无需搜索整个表即可快速查找。
【讨论】:
【参考方案5】:-- 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
【讨论】:
喜欢这个是因为不需要经常维护并行表。以上是关于如何检查表是不是包含Lua中的元素?的主要内容,如果未能解决你的问题,请参考以下文章