Wie kann man prüfen, ob eine Tabelle ein Element in Lua enthält?
Frage
Gibt es eine Methode zur Überprüfung, ob eine Tabelle enthält einen Wert? Ich habe meine eigene (naive) Funktion, aber ich frage mich, ob etwas „offizielle“ für das existiert? Oder etwas effizienter ...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
Übrigens, der Hauptgrund, warum ich diese Funktionen bin mit Tabellen ist als Sätze zu verwenden, dh ohne doppelte Elemente. Gibt es etwas, sonst könnte ich verwenden?
Lösung
Sie können die Werte wie die Tasten des Tisches. Zum Beispiel:
function addToSet(set, key)
set[key] = true
end
function removeFromSet(set, key)
set[key] = nil
end
function setContains(set, key)
return set[key] ~= nil
end
Es gibt ein voll funktionsfähiges Beispiel hier .
Andere Tipps
Angesichts Ihrer Darstellung, Ihre Funktion ist so effizient wie getan werden kann. Natürlich, wie andere schon angemerkt (und wie in Sprachen älter als Lua praktiziert), ist die Lösung für Ihr eigentliches Problem Änderung Darstellung. Wenn Sie Tabellen und Sie Sätze wollen, schalten Sie Tabellen in Gruppen durch das Set-Element als Schlüssel und true
als Wert verwendet wird. +1 bis interjay.
Ich kann nicht von einer anderen Art und Weise denkt, Wert zu vergleichen, aber wenn Sie das Element des Satzes als Schlüssel verwenden, können Sie den Wert auf etwas anderes als Null gesetzt. Dann erhalten Sie schnellen Lookups ohne die gesamte Tabelle suchen zu müssen.
Ich weiß, das ist eine alte Post, aber ich wollte etwas für die Nachwelt hinzuzufügen. Der einfache Weg, um das Problem der Handhabung, dass Sie haben, ist eine andere Tabelle zu machen, der Wert zu drücken.
dh. Sie haben zwei Tabellen, die den gleichen Wert haben, eine eine Richtung zeigen, das eine das andere zeigt.
function addValue(key, value)
if (value == nil) then
removeKey(key)
return
end
_primaryTable[key] = value
_secodaryTable[value] = key
end
function removeKey(key)
local value = _primaryTable[key]
if (value == nil) then
return
end
_primaryTable[key] = nil
_secondaryTable[value] = nil
end
function getValue(key)
return _primaryTable[key]
end
function containsValue(value)
return _secondaryTable[value] ~= nil
end
Sie können dann die neue Tabelle abfragen, um zu sehen, ob es die Taste ‚Element‘ hat. Dies verhindert, dass die Notwendigkeit zu durchlaufen jeden Wert der anderen Tabelle.
Wenn es sich herausstellt, dass Sie nicht wirklich das ‚Element‘ als Schlüssel verwenden können, weil es zum Beispiel kein String ist, fügen Sie dann eine Prüfsumme oder tostring
auf es zum Beispiel, und dann, dass als Schlüssel verwenden.
Warum wollen Sie das tun? Wenn Ihre Tabellen sehr groß sind, wird die Höhe der Zeit zu durchlaufen jedes Element von Bedeutung sein, zu verhindern, dass Sie es sehr oft zu tun. Der zusätzliche Speicher-Overhead wird relativ gering sein, da es 2 Zeiger auf das gleiche Objekt zu speichern kann, anstatt zwei Kopien des gleichen Objekts. Wenn Ihre Tabellen sehr klein sind, dann wird es viel weniger wichtig, infact es sogar schneller als auf Iterierte sein kann eine andere Karte Nachschlag zu haben.
Der Wortlaut der Frage jedoch stark darauf hin, dass Sie eine große Anzahl von Elementen zu tun haben.