Cerca un elemento in un elenco Lua
Domanda
Se ho un elenco di elementi come questo:
local items = { "apple", "orange", "pear", "banana" }
come posso verificare se " arancione " è in questo elenco?
In Python potrei fare:
if "orange" in items:
# do something
Esiste un equivalente in Lua?
Soluzione
Puoi usare qualcosa come un set da Programmazione in Lua :
function Set (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
Quindi potresti mettere la tua lista nel Set e testare l'appartenenza:
local items = Set { "apple", "orange", "pear", "banana" }
if items["orange"] then
-- do something
end
Oppure puoi scorrere direttamente l'elenco:
local items = { "apple", "orange", "pear", "banana" }
for _,v in pairs(items) do
if v == "orange" then
-- do something
break
end
end
Altri suggerimenti
Utilizza invece la seguente rappresentazione:
local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
...
end
Stai vedendo in prima persona uno dei contro di Lua che ha solo una struttura di dati --- devi fare il tuo. Se rimani con Lua accumulerai gradualmente una libreria di funzioni che manipolano le tabelle nel modo in cui ti piace fare le cose. La mia libreria include una conversione da elenco a set e una funzione di ricerca elenco di ordine superiore:
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
Le tabelle Lua sono più simili ai dizionari Python che alle liste. La tabella che hai creato è essenzialmente una matrice di stringhe indicizzata basata su 1. Utilizzare qualsiasi algoritmo di ricerca standard per scoprire se nell'array è presente un valore. Un altro approccio sarebbe quello di memorizzare i valori come chiavi di tabella invece come mostrato nell'implementazione impostata del post di 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
Ecco la funzione che uso per verificare se i dati sono in un array.
Ordinamento della soluzione usando 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
Questa è una funzione di coltellino svizzero che puoi usare:
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
Puoi usarlo per verificare se esiste un valore:
local myFruit = "apple"
if (table.find({"apple", "pear", "berry"}, myFruit)) then
print(table.find({"apple", "pear", "berry"}, myFruit)) -- 1
Puoi usarlo per trovare la chiave:
local fruits = {
apple = {color="red"},
pear = {color="green"},
}
local myFruit = fruits.apple
local fruitName = table.find(fruits, myFruit)
print(fruitName) -- "apple"
Spero che il parametro ricorsivo
parli da solo.
Il parametro metatables
consente anche di cercare metatables.
Il parametro keys
consente alla funzione di cercare i tasti nell'elenco. Naturalmente sarebbe inutile in Lua (puoi semplicemente fare frutti [chiave]
) ma insieme a ricorsivo
e metatables
, diventa utile.
Il parametro returnBool
è una protezione per quando ci sono tabelle che hanno false
come chiave in una tabella (Sì, è possibile: fruits = { falso = " mela "}
)