2009-03-17 8 views
40

Wenn ich eine Liste von Elementen wie diese:Suche nach einem Elemente in einer Lua Liste

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 

ein Äquivalent in Lua Gibt es?

Antwort

63

Man könnte so etwas wie eine Reihe von Programming 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 
4

Lua Tabellen sind Analoga von Python dictio Naries statt Listen. Die Tabelle, die Sie erstellen, ist im Wesentlichen ein 1-basiertes indiziertes Array von Strings. Verwenden Sie einen beliebigen Standardsuchalgorithmus, um herauszufinden, ob sich ein Wert im Array befindet. Ein anderer Ansatz wäre, die Werte als Tabellenschlüssel zu speichern, wie in der Implementierung von Jon Ericson gezeigt.

22

die folgende Darstellung Verwenden Sie stattdessen:

local items = { apple=true, orange=true, pear=true, banana=true } 
if items.apple then 
    ... 
end 
+2

Dies ist der beste Weg, um einen Satz zu machen (in den reinen mathematischen Sinn) der Dinge in Lua. Bravo! Da es jedoch kein Ordnungskonzept hat, beantwortet es nicht unbedingt die allgemeine Frage "Suche nach einem Objekt in einer Lua-Liste?" wenn die Reihenfolge der Listen zählt. – Mark

+0

Das fühlt sich so viel eleganter an. Habe es einfach benutzt, um eine Tabelle zu erstellen, die aussah wie '{thingIAmLookingFor: true, secondThingIAmLookingFor: true}' –

+0

Scheint nicht mit Zahlen zu arbeiten. – CalculatorFeline

17

Sie aus erster Hand, einer der Nachteile von Lua mit nur einer Datenstruktur zu sehen --- müssen Sie Ihre eigene Rolle. Wenn Sie bei Lua bleiben, werden Sie nach und nach eine Bibliothek von Funktionen ansammeln, die Tabellen so manipulieren, wie Sie Dinge tun. Meine Bibliothek enthält eine Liste zu setzen 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 
+6

Dies ist keine Konsequenz, eine Datenstruktur zu haben, es ist nur eine Konsequenz von Lua, die eine beschissene Standardbibliothek hat. –

1

Sortieren der Lösung Metatabelle mit ...

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 
+0

Wie unterscheidet sich das von '' 'lokalen Arbeitstisch ist = {} Arbeitstisch [123] = true Arbeitstisch [456] wahr wenn Arbeitstisch [456] dann ... end''' = –

2
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 verwende um zu prüfen, ob Daten in einem Array sind.

1

Dies ist eine Schweizer-armyknife Funktion können Sie:

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 es verwenden können, wenn ein Wert vorhanden ist zu überprüfen:

local myFruit = "apple" 
if (table.find({"apple", "pear", "berry"}, myFruit)) then 
    print(table.find({"apple", "pear", "berry"}, myFruit)) -- 1 

Sie es den Schlüssel finden verwenden können:

Ich hoffe, der recursive Parameter spricht für sich.

Der Parameter metatables ermöglicht es Ihnen auch Metatabellen zu suchen.

Der Parameter keys lässt die Funktion nach Schlüsseln in der Liste suchen. Natürlich wäre das in Lua nutzlos (Sie können einfach fruits[key] tun), aber zusammen mit recursive und metatables wird es praktisch.

Der returnBool Parameter ist ein Schutz für die, wenn Sie Tabellen, die false als Schlüssel in einer Tabelle (Ja, das ist möglich: fruits = {false="apple"}) haben