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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top