Si j'ai une liste d'articles comme celui-ci:
local items = { "Apple", "orange", "pear", "banana" }
comment vérifier si "orange" est dans cette liste?
En Python je pourrais faire:
if "orange" in items:
# do something
Y a-t-il un équivalent à Lua?
Vous pouvez utiliser quelque chose comme un ensemble de Programmation en Lua :
function Set (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
Ensuite, vous pouvez mettre votre liste dans l'ensemble et tester l'adhésion:
local items = Set { "Apple", "orange", "pear", "banana" }
if items["orange"] then
-- do something
end
Ou vous pouvez parcourir la liste directement:
local items = { "Apple", "orange", "pear", "banana" }
for _,v in pairs(items) do
if v == "orange" then
-- do something
break
end
end
Utilisez plutôt la représentation suivante:
local items = { Apple=true, orange=true, pear=true, banana=true }
if items.Apple then
...
end
Vous voyez de première main l'un des inconvénients de Lua n'ayant qu'une seule structure de données --- vous devez lancer la vôtre. Si vous vous en tenez à Lua, vous accumulerez progressivement une bibliothèque de fonctions qui manipulent les tableaux de la manière dont vous aimez faire les choses. Ma bibliothèque comprend une conversion de liste en ensemble et une fonction de recherche de liste d'ordre supérieur:
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
Les tables Lua sont des analogues plus proches des dictionnaires Python plutôt que des listes. La table que vous avez créée est essentiellement un tableau indexé basé sur 1. Utilisez n'importe quel algorithme de recherche standard pour savoir si une valeur est dans le tableau. Une autre approche serait de stocker les valeurs sous forme de clés de table à la place, comme indiqué dans l'implémentation d'ensemble du message de Jon Ericson.
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
Voici la fonction que j'utilise pour vérifier si les données sont dans un tableau.
Il s'agit d'une fonction swiss-armyknife que vous pouvez utiliser:
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
Vous pouvez l'utiliser pour vérifier si une valeur existe:
local myFruit = "Apple"
if (table.find({"Apple", "pear", "berry"}, myFruit)) then
print(table.find({"Apple", "pear", "berry"}, myFruit)) -- 1
Vous pouvez l'utiliser pour trouver la clé:
local fruits = {
Apple = {color="red"},
pear = {color="green"},
}
local myFruit = fruits.Apple
local fruitName = table.find(fruits, myFruit)
print(fruitName) -- "Apple"
J'espère que le paramètre recursive
parle de lui-même.
Le paramètre metatables
vous permet également de rechercher des métatables.
Le paramètre keys
permet à la fonction de rechercher des clés dans la liste. Bien sûr, cela serait inutile à Lua (vous pouvez simplement faire fruits[key]
) mais avec recursive
et metatables
, cela devient pratique.
Le paramètre returnBool
est un garde-fou lorsque vous avez des tables qui ont false
comme clé dans une table (Oui c'est possible: fruits = {false="Apple"}
)
Sorte de solution utilisant 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