Wenn ich eine Liste mit Artikeln wie diesen habe:
local items = { "Apple", "orange", "pear", "banana" }
wie überprüfe ich, ob "orange" in dieser Liste enthalten ist?
In Python könnte ich tun:
if "orange" in items:
# do something
Gibt es ein Äquivalent in Lua?
Sie könnten so etwas wie ein Set aus 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 in das Set setzen und auf Mitgliedschaft testen:
local items = Set { "Apple", "orange", "pear", "banana" }
if items["orange"] then
-- do something
end
Oder Sie können die Liste direkt durchlaufen:
local items = { "Apple", "orange", "pear", "banana" }
for _,v in pairs(items) do
if v == "orange" then
-- do something
break
end
end
Verwenden Sie stattdessen die folgende Darstellung:
local items = { Apple=true, orange=true, pear=true, banana=true }
if items.Apple then
...
end
Sie sehen aus erster Hand, dass eines der Nachteile von Lua nur eine Datenstruktur hat - Sie müssen Ihre eigene rollen. Wenn Sie sich an Lua halten, werden Sie nach und nach eine Bibliothek von Funktionen aufbauen, mit denen Sie Tabellen nach Ihren Wünschen bearbeiten können. Meine Bibliothek enthält eine List-to-Set-Konvertierung und eine übergeordnete Listensuchfunktion:
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 eher Analoga von Python Wörterbüchern als von Listen. Die von Ihnen erstellte Tabelle ist im Wesentlichen ein 1-basiertes indiziertes Array von Zeichenfolgen. Verwenden Sie einen beliebigen Standardsuchalgorithmus, um herauszufinden, ob ein Wert vorhanden ist Ein anderer Ansatz wäre, die Werte als Tabellenschlüssel zu speichern, wie in der Set-Implementierung von Jon Ericsons 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, mit der ich überprüfe, ob sich Daten in einem Array befinden.
Dies ist eine Schweizer Taschenmesser-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 damit prü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 Parameter recursive
spricht für sich.
Mit dem Parameter metatables
können Sie auch nach Metatabellen suchen.
Mit dem Parameter keys
sucht die Funktion nach Schlüsseln in der Liste. Natürlich wäre das in Lua nutzlos (du kannst nur fruits[key]
) aber zusammen mit recursive
und metatables
wird es praktisch.
Der Parameter returnBool
ist ein Schutz für Tabellen, die false
als Schlüssel in einer Tabelle haben (Ja, das ist möglich: fruits = {false="Apple"}
)
Art der Lösung mit 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