list 在 Lua 列表中搜索项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/656199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Search for an item in a Lua list
提问by Jay
If I have a list of items like this:
如果我有这样的项目列表:
local items = { "apple", "orange", "pear", "banana" }
how do I check if "orange" is in this list?
如何检查“橙色”是否在此列表中?
In Python I could do:
在 Python 中,我可以这样做:
if "orange" in items:
# do something
Is there an equivalent in Lua?
Lua中是否有等价物?
回答by Jon Ericson
You could use something like a set from Programming in Lua:
您可以使用来自Programming in Lua 中的 set 之类的东西:
function Set (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
Then you could put your list in the Set and test for membership:
然后您可以将您的列表放入 Set 并测试成员资格:
local items = Set { "apple", "orange", "pear", "banana" }
if items["orange"] then
-- do something
end
Or you could iterate over the list directly:
或者您可以直接遍历列表:
local items = { "apple", "orange", "pear", "banana" }
for _,v in pairs(items) do
if v == "orange" then
-- do something
break
end
end
回答by Jay
Use the following representation instead:
请改用以下表示:
local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
...
end
回答by Norman Ramsey
You're seeing firsthand one of the cons of Lua having only one data structure---you have to roll your own. If you stick with Lua you will gradually accumulate a library of functions that manipulate tables in the way you like to do things. My library includes a list-to-set conversion and a higher-order list-searching function:
您亲眼目睹了 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
回答by Judge Maygarden
Lua tables are more closely analogs of Python dictionaries rather than lists. The table you have create is essentially a 1-based indexed array of strings. Use any standard search algorithm to find out if a value is in the array. Another approach would be to store the values as table keys instead as shown in the set implementation of Jon Ericson's post.
Lua 表更接近于 Python 字典而不是列表。您创建的表本质上是一个基于 1 的索引字符串数组。使用任何标准搜索算法来确定某个值是否在数组中。另一种方法是将值存储为表键,而不是如 Jon Ericson 帖子的集合实现中所示。
回答by KingofGamesYami
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
Here's the function I use for checking if data is in an array.
这是我用于检查数据是否在数组中的函数。
回答by Luc Bloom
This is a swiss-armyknife function you can use:
这是您可以使用的 swiss-armyknife 功能:
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
You can use it to check if a value exists:
您可以使用它来检查值是否存在:
local myFruit = "apple"
if (table.find({"apple", "pear", "berry"}, myFruit)) then
print(table.find({"apple", "pear", "berry"}, myFruit)) -- 1
You can use it to find the key:
您可以使用它来查找密钥:
local fruits = {
apple = {color="red"},
pear = {color="green"},
}
local myFruit = fruits.apple
local fruitName = table.find(fruits, myFruit)
print(fruitName) -- "apple"
I hope the recursive
parameter speaks for itself.
我希望recursive
参数不言自明。
The metatables
parameter allows you to search metatables as well.
该metatables
参数还允许您搜索元表。
The keys
parameter makes the function look for keys in the list. Of course that would be useless in Lua (you can just do fruits[key]
) but together with recursive
and metatables
, it becomes handy.
该keys
参数使函数在列表中查找键。当然,这在 Lua 中是没用的(你可以直接做fruits[key]
),但是与recursive
和一起metatables
,它变得很方便。
The returnBool
parameter is a safe-guard for when you have tables that have false
as a key in a table (Yes that's possible: fruits = {false="apple"}
)
该returnBool
参数是一个安全守卫,因为当你有一个有表false
为表中的一个键(是的,这是可能的:fruits = {false="apple"}
)
回答by Konstantin Artemiev
Sort of solution using metatable...
使用元表的解决方案......
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