web-dev-qa-db-ger.com

Suche nach einem Gegenstand in einer Lua-Liste

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?

48
Jay

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
73
Jon Ericson

Verwenden Sie stattdessen die folgende Darstellung:

local items = { Apple=true, orange=true, pear=true, banana=true }
if items.Apple then
    ...
end
25
fsanbr

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
17
Norman Ramsey

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.

3
Judge Maygarden
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.

2
KingofGamesYami

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"})

1
Luc Bloom

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
1