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

时间:2010-02-17 16:32:32

标签: lua set unique contains lua-table

是否有检查表是否包含值的方法?我有自己的(幼稚)功能,但我想知道是否存在“正式”的东西?或者更高效的东西...

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

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

5 个答案:

答案 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