Lua中如何检查表中是否包含特定值

我正在寻找一种方法来查看数组(表)中是否有特定值

该示例表有3个条目,每个条目包含具有多个条目的表

假设我正在检查是否在'data'中有'apple'

  data = {
{"alpha","bravo","charlie","delta"},
{"apple","kiwi","banana","pear"},
{"carrot","brocoli","cabage","potatoe"}
}

这是我拥有的代码 - 递归查询。 问题在于该函数中某处出现问题,因为它删除了正值

local function hasValue(tbl, str)

local f = false

    for ind, val in pairs(tbl) do

            if type(val) == "table" then

                hasValue(val, str)

            else
                    if type(val) == "string" then

                        if string.gsub(val, '^%s*(.-)%s*$', '%1') == string.gsub(str, '^%s*(.-)%s*$', '%1') then
                            f = true
                        end

                    end
            end
    end

return f end

任何关于该问题或者替代方法的帮助将不胜感激。

这里是完整的测试文件

点赞
用户8621712
用户8621712

帮助:

  • 你可以使用 string.gsub 并匹配整个字符串,但不包括尾部空格。在你的例子中,你根本没有尾部空格,因此这是一个无意义的函数调用和比较。在这种情况下,你应该直接字符串比较 if val == str then
  • 当你使用 f = true 时,函数仍然会运行直到遍历完所有项,因此即使它找到了某些东西,它也会浪费你的 CPU 时间。你应该使用 return true,因为它找到了该项,不需要继续。

解决方案 1:

  • 最好的解决方案是对所有项进行表查找(集合列表)。创建一个名为 lookup = {} 的表,并在你执行 table.insert(a, b) 之前/之后,迭代 b 并将所有项添加到查找表中。
for k, v in ipairs(b) do
    lookup[v] = true
end

这将从 b 中提取值作为 lookup 中的键,值 true 只是指示我们有该键。 稍后,如果您想知道是否有此项,只需执行 print("Has brocoli:", lookup["brocoli"])

解决方案 2:

  • 这个解决方案更慢,但不需要使用额外的表。只需修复 hasValue 函数即可。
function hasValue(tbl, value)
    for k, v in ipairs(tbl) do -- 迭代表(仅适用于顺序表)
        if v == value or (type(v) == "table" and hasValue(v, value)) then -- 直接将表中的值与我们正在查找的值进行比较,否则如果值是表,则检查其内容是否为该值。
            return true -- 在此或嵌套表格中找到
        end
    end
    return false -- 没有找到
end

注:此函数不能处理非顺序数组。对于你的代码,它将有效。

2020-11-06 16:24:24
用户2898815
用户2898815

感谢 @codeflush.dev 的回答

-- 判断table中是否包含指定的字符串
local function hasValue(tbl, str)
    local f = false
    for ind, val in pairs(tbl) do
        if type(val) == "table" then
            f = hasValue(val, str)
        else
            if type(val) == "string" then
                if string.gsub(val, '^%s*(.-)%s*$', '%1') == string.gsub(str, '^%s*(.-)%s*$', '%1') then
                    f = true
                end
            end
        end
    end
    return f
end
2020-11-06 16:26:28
用户3342050
用户3342050
local function hasValue( tbl, str )
    local f = false
    for i = 1, #tbl do
        if type( tbl[i] ) == "table" then
            f = hasValue( tbl[i], str )  --  返回递归值
            if f then break end  --  如果返回 true,则跳出循环
        elseif tbl[i] == str then
            return true
        end
    end
    return f
end

print( hasValue( data, 'apple' ) )
print( hasValue( data, 'dog' ) )

true

false

2020-11-06 16:41:26