Suchen nach einem Element in einer Liste Lua
Frage
Wenn ich eine Liste der Elemente wie folgt aus:
local items = { "apple", "orange", "pear", "banana" }
Wie kann ich überprüfen, ob "orange" in dieser Liste?
In Python könnte ich tun:
if "orange" in items:
# do something
Gibt es ein Äquivalent in Lua?
Lösung
Man könnte so etwas wie eine Reihe von Programmierung in Lua verwenden:
function Set (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end
Dann könnten Sie Ihre Liste im Set und Test für die Mitgliedschaft setzen:
local items = Set { "apple", "orange", "pear", "banana" }
if items["orange"] then
-- do something
end
Oder Sie könnten über die Liste iterieren direkt:
local items = { "apple", "orange", "pear", "banana" }
for _,v in pairs(items) do
if v == "orange" then
-- do something
break
end
end
Andere Tipps
Verwenden Sie die folgende Darstellung statt:
local items = { apple=true, orange=true, pear=true, banana=true }
if items.apple then
...
end
Sie aus erster Hand, einer der Nachteile von Lua mit nur einer Datenstruktur zu sehen --- Sie haben Ihre eigene Rolle. Wenn Sie mit Lua-Stick werden Sie nach und nach eine Bibliothek von Funktionen sammeln, die Tabellen in der Art und Weise manipulieren Sie mögen es, Dinge zu tun. Meine Bibliothek enthält eine Liste-to-Set-Umwandlung und eine höhere Ordnung list-Suchfunktion:
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
Lua Tabellen sind enger Analoga von Python Wörterbücher statt Listen. Die Tabelle, die Sie erstellen müssen, ist im Wesentlichen ein 1-basierter indiziertes Array von Strings. Verwenden Sie eine beliebigen Standard-Suchalgorithmus, um herauszufinden, ob ein Wert in dem Array ist. Ein anderer Ansatz wäre die Werte als Tabellenschlüssel anstatt zu speichern, wie sie in der Menge Implementierung von Jon Ericson Beitrag gezeigt.
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
Hier ist die Funktion, die ich für die Überprüfung verwenden, wenn Daten in einem Array.
Eine Art Lösung mit Metatabelle ...
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
Dies ist eine Schweizer-armyknife Funktion, die Sie verwenden können:
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
Sie können es verwenden, um zu überprüfen, ob ein Wert vorhanden ist:
local myFruit = "apple"
if (table.find({"apple", "pear", "berry"}, myFruit)) then
print(table.find({"apple", "pear", "berry"}, myFruit)) -- 1
Sie können es verwenden, um den Schlüssel zu finden:
local fruits = {
apple = {color="red"},
pear = {color="green"},
}
local myFruit = fruits.apple
local fruitName = table.find(fruits, myFruit)
print(fruitName) -- "apple"
Ich hoffe, der recursive
Parameter für sich selbst spricht.
Der metatables
Parameter können Sie Metatables auch suchen.
Der keys
Parameter macht die Funktion sucht Schlüssel in der Liste. Natürlich die nutzlos in Lua wäre (man kann fruits[key]
gerade tun), aber zusammen mit recursive
und metatables
wird es praktisch.
Der returnBool
Parameter ist ein Schutz für die, wenn Sie Tabellen, die als Schlüssel in einer Tabelle false
haben (Ja, das ist möglich: fruits = {false="apple"}
)