在 Lua 列表中搜索一个项。
如果我有这样一个项目列表:
local items = {"apple", "orange", "pear", "banana"}
我如何检查“orange”是否在此列表中?
在 Python 中,我可以这样做:
if "orange" in items:
# do something
Lua 中有等价的吗?
原文链接 https://stackoverflow.com/questions/656199
Lua的表更类似于Python中的字典,而不是列表。你创建的表实际上是一个基于1的索引字符串数组。可以使用任何标准搜索算法来查找数组中是否有一个值。另一种方法是将值存储为表键,如Jon Ericson发布的set实现所示。
请改用下面的表示方式:
local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
...
end
你现在看到的是 Lua 只有一个数据结构的缺点之一 --- 你必须自己来实现。如果你选择使用 Lua,你将逐渐积累一个库,其中包括能够按照你想要的方式操作表格的函数。我的库包括一个将列表转换为集合的函数和一个高阶列表搜索函数:
function table.set(t) -- 列表转集合
local u = { }
for _, v in ipairs(t) do u[v] = true end
return u
end
function table.find(f, l) -- 查找元素 v 使其满足 f(v)
for _, v in ipairs(l) do
if f(v) then
return v
end
end
return nil
end
使用元表的一种解决方案...
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
使用元表的一种解决方案...
以下是我用于检查数据是否在数组中的函数。
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
这是一个你可以使用的多功能函数:
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]
),但是与 recursive
和 metatables
结合起来,它变得很方便。
returnBool
参数是一个安全保障,当你的表中有 false
作为一个键时它会很有用(是的,这是可能的:fruits = {false="apple"}
)
```lua
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
```lua
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
你可以使用以下解决方案:
items = { 'a', 'b' }
for k,v in pairs(items) do
if v == 'a' then
--做一些事情
else
--做一些事情
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
#! /usr/bin/env lua
local items = { 'apple', 'orange', 'pear', 'banana' }
-- 定义函数 locate,查找 table 中是否包含 value
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' 及 'car'
locate( items, 'orange' )
locate( items, 'car' )
输出:
orange found
car not found
一个简单的函数可以用来:
- 如果表中没有找到该项,则返回 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
下面的表达可以被使用:
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.
请查看Tables Tutorial获取其他信息。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你可以使用像 Programming in Lua 中的集合:
function Set (list) local set = {} for _, l in ipairs(list) do set[l] = true end return set end
然后,您可以将列表放入集合中并测试成员资格:
local items = Set { "apple", "orange", "pear", "banana" } if items["orange"] then -- 做些什么 end
或者直接迭代列表:
local items = { "apple", "orange", "pear", "banana" } for _,v in pairs(items) do if v == "orange" then -- 做些什么 break end end