如何检查表是否包含Lua中的元素?


97

有没有检查表是否包含值的方法?我有自己的(幼稚)功能,但是我想知道是否为此存在“官方”功能?还是更有效率的...

function table.contains(table, element)
  for _, value in pairs(table) do
    if value == element then
      return true
    end
  end
  return false
end

顺便说一句,我使用此函数的主要原因是将表用作集合,即没有重复的元素。还有其他我可以使用的东西吗?


3
_表示法是什么意思?
马丁2010年

24
它只是一个名为的“垃圾”变量_pairs()返回key, value,但在此示例中,我仅需要该值。使用此变量存储不需要的东西是一种惯例(在“ Lua编程”一书中通过了lua.org/pil/index.html_
Wookai'2

我也看到了命名_Python和JavaScript中使用的“垃圾”变量的约定。
iono

Answers:


116

您可以将值用作表的键。例如:

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

还有一个功能更全面例如这里


13
匿名用户建议对您的代码进行以下修复:如果具有指定键的集合中的值为FALSE,则尽管表中存在具有指定键的项,但函数setContains()返回false。“ return set [key]〜= nil”行修复了该错误。
oers 2012年

或许也function keysOfSet(set) local ret={} for k,_ in pairs(set) do ret[#ret+1]=k end return ret end
杰西·奇泽姆

24

有了您的代表,您的功能就可以高效完成。 当然,正如其他人所指出的(以及使用比Lua古老的语言所实践的),解决您真正的问题的方法是更改​​表示形式。当您有表并需要集合时,可以通过使用set元素作为键和true值将表转变为集合。+1进行互动。


2

我想不出另一种比较值的方法,但是如果您将集合的元素用作键,则可以将值设置为nil以外的任何值。这样您便可以快速查找,而不必搜索整个表。


2

我知道这是一篇旧文章,但我想为后代添加一些内容。处理您所遇到的问题的简单方法是制作另一个具有关键价值的表。

即。您有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”。这样可以避免遍历另一个表的每个值的需要。

如果事实证明您实际上不能使用'element'作为键,例如因为它不是字符串,则添加校验和或 tostring例如在其上,然后将其用作键。

你为什么要这样做?如果表很大,则遍历每个元素的时间将很长,从而使您无法经常执行此操作。额外的内存开销将相对较小,因为它将存储2个指向同一对象的指针,而不是2个相同对象的副本。如果您的表很小,那么事情就不那么重要了,实际上,迭代甚至比进行另一个地图查找要快。

但是,问题的措词强烈暗示您需要处理很多项目。


很好的解释,但并没有真正增加讨论的内容。编辑interjay的答案可能是一个更好的主意。
bcdan 2015年

1
另外,在此代码中的任何位置都应将“ .key”替换为“ [key]”(与“ value”相同)
Njol
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.