61

如果我有这样的项目列表:

local items = { "apple", "orange", "pear", "banana" }

如何检查“橙色”是否在此列表中?

在 Python 中,我可以这样做:

if "orange" in items:
    # do something

Lua中是否有等价物?

4

12 回答 12

85

您可以使用类似于Programming in Lua 中的集合:

function Set (list)
  local set = {}
  for _, l in ipairs(list) do set[l] = true end
  return set
end

然后您可以将您的列表放入 Set 并测试成员资格:

local items = Set { "apple", "orange", "pear", "banana" }

if items["orange"] then
  -- do something
end

或者您可以直接遍历列表:

local items = { "apple", "orange", "pear", "banana" }

for _,v in pairs(items) do
  if v == "orange" then
    -- do something
    break
  end
end
于 2009-03-17T22:08:36.557 回答
33

请改用以下表示:

local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
    ...
end
于 2009-03-17T22:19:58.683 回答
20

你亲眼目睹了 Lua 只有一个数据结构的缺点——你必须自己动手。如果您坚持使用 Lua,您将逐渐积累一个以您喜欢的方式操作表的函数库。我的库包括一个列表到集合的转换和一个高阶列表搜索功能:

function table.set(t) -- set of list
  local u = { }
  for _, v in ipairs(t) do u[v] = true end
  return u
end

function table.find(f, l) -- find element v of l satisfying f(v)
  for _, v in ipairs(l) do
    if f(v) then
      return v
    end
  end
  return nil
end
于 2009-03-20T00:30:51.260 回答
3

Lua 表更类似于 Python 字典而不是列表。您创建的表本质上是一个基于 1 的索引字符串数组。使用任何标准搜索算法来确定数组中是否有值。另一种方法是将值存储为表键,而不是如 Jon Ericson 的帖子的 set implementation 所示。

于 2009-03-17T22:13:51.723 回答
3

这是您可以使用的瑞士军刀功能:

function table.find(t, val, recursive, metatables, keys, returnBool)
    if (type(t) ~= "table") then
        return nil
    end

    local checked = {}
    local _findInTable
    local _checkValue
    _checkValue = function(v)
        if (not checked[v]) then
            if (v == val) then
                return v
            end
            if (recursive and type(v) == "table") then
                local r = _findInTable(v)
                if (r ~= nil) then
                    return r
                end
            end
            if (metatables) then
                local r = _checkValue(getmetatable(v))
                if (r ~= nil) then
                    return r
                end
            end
            checked[v] = true
        end
        return nil
    end
    _findInTable = function(t)
        for k,v in pairs(t) do
            local r = _checkValue(t, v)
            if (r ~= nil) then
                return r
            end
            if (keys) then
                r = _checkValue(t, k)
                if (r ~= nil) then
                    return r
                end
            end
        end
        return nil
    end

    local r = _findInTable(t)
    if (returnBool) then
        return r ~= nil
    end
    return r
end

您可以使用它来检查值是否存在:

local myFruit = "apple"
if (table.find({"apple", "pear", "berry"}, myFruit)) then
    print(table.find({"apple", "pear", "berry"}, myFruit)) -- 1

您可以使用它来查找密钥:

local fruits = {
    apple = {color="red"},
    pear = {color="green"},
}
local myFruit = fruits.apple
local fruitName = table.find(fruits, myFruit)
print(fruitName) -- "apple"

我希望recursive参数不言自明。

metatables参数还允许您搜索元表。

keys参数使函数在列表中查找键。当然,这在 Lua 中是没有用的(你可以这样做fruits[key]),但与recursiveand一起metatables,它变得很方便。

当您的表在表中作为键时,该returnBool参数是一种保护措施(是的,这是可能的:)falsefruits = {false="apple"}

于 2016-10-20T08:31:18.177 回答
3

随心所欲地编写它,但是直接遍历 list比生成 pairs() 或 ipairs() 更快

#! /usr/bin/env lua

local items = { 'apple', 'orange', 'pear', 'banana' }

local function locate( table, value )
    for i = 1, #table do
        if table[i] == value then print( value ..' found' ) return true end
    end
    print( value ..' not found' ) return false
end

locate( items, 'orange' )
locate( items, 'car' )

橙色 发现
没有找到车

于 2020-11-03T15:10:04.353 回答
2
function valid(data, array)
 local valid = {}
 for i = 1, #array do
  valid[array[i]] = true
 end
 if valid[data] then
  return false
 else
  return true
 end
end

这是我用来检查数据是否在数组中的函数。

于 2014-04-11T14:42:32.833 回答
1

使用元表的解决方案...

local function preparetable(t)
 setmetatable(t,{__newindex=function(self,k,v) rawset(self,v,true) end})
end

local workingtable={}
preparetable(workingtable)
table.insert(workingtable,123)
table.insert(workingtable,456)

if workingtable[456] then
...
end
于 2013-03-29T15:07:48.067 回答
0
function table.find(t,value)
    if t and type(t)=="table" and value then
        for _, v in ipairs (t) do
            if v == value then
                return true;
            end
        end
        return false;
    end
    return false;
end
于 2020-07-24T20:49:42.183 回答
0

您可以使用此解决方案:

items = { 'a', 'b' }
for k,v in pairs(items) do 
 if v == 'a' then 
  --do something
 else 
  --do something
 end
end

或者

items = {'a', 'b'}
for k,v in pairs(items) do 
  while v do
    if v == 'a' then 
      return found
    else 
      break
    end
  end 
 end 
return nothing
于 2020-10-27T17:31:00.773 回答
0

可以使用一个简单的函数:

  • 如果在表中未找到该项目,则返回 nil
  • 如果在表中找到项目,则返回项目的索引
local items = { "apple", "orange", "pear", "banana" }

local function search_value (tbl, val)
    for i = 1, #tbl do
        if tbl[i] == val then
            return i
        end
    end
    return nil
end

print(search_value(items, "pear"))
print(search_value(items, "cherry"))

上述代码的输出将是

3
nil
于 2021-05-01T17:57:19.260 回答
0

可以使用以下表示:

local items = {
    ["apple"]=true, ["orange"]=true, ["pear"]=true, ["banana"]=true
}

if items["apple"] then print("apple is a true value.") end
if not items["red"] then print("red is a false value.") end

相关输出:

apple is a true value.
red is a false value.

您还可以使用以下代码检查布尔值的有效性:

local items = {
    ["apple"]=true, ["orange"]=true, ["pear"]=true, ["banana"]=true,
    ["red"]=false, ["blue"]=false, ["green"]=false
}

if items["yellow"] == nil then print("yellow is an inappropriate value.") end
if items["apple"] then print("apple is a true value.") end
if not items["red"] then print("red is a false value.") end

输出是:

yellow is an inappropriate value.
apple is a true value.
red is a false value.

查看表格教程以获取更多信息。

于 2021-08-31T07:35:11.483 回答