Frage

Warum kann ich nicht table.sort zu sortieren Tabellen mit assoziativen Indizes verwenden?

War es hilfreich?

Lösung

Sie können nur sortieren Tabellen mit aufeinanderfolgenden ganzen Tasten beginnend bei 1, das heißt Listen. Wenn Sie eine andere Tabelle von Schlüssel-Wert-Paaren haben, können Sie eine Liste von Paaren zu machen und zu sortieren, dass:

function sortpairs(t, lt)
  local u = { }
  for k, v in pairs(t) do table.insert(u, { key = k, value = v }) end
  table.sort(u, lt)
  return u
end

Natürlich ist dies ist nur sinnvoll, wenn Sie eine benutzerdefinierte Bestellung liefern (lt), die als Argument Schlüssel / Wert-Paare erwartet.

Dieses Problem wird noch ausführlicher in einer damit verbundenen Frage über das Sortieren diskutiert Lua Tabellen .

Andere Tipps

Generell Lua Tabellen sind reine assoziative Arrays. Es gibt kein „natürlichen“, um andere als die als Nebenwirkung von der jeweiligen Implementierung des Hash-Tabelle in Lua Kern verwendet. Dies macht Sinn, da die Werte von jedem Lua Datentyp (außer nil) können sowohl als Schlüssel und Werte verwendet werden; aber nur Strings und Zahlen haben jede Art von sinnvoller Ordnung, und dann auch nur zwischen den Werten der gleichen Typ.

Zum Beispiel, was sollte die sortierten Reihenfolge dieser Tabelle sein:

unsortable = {
    answer=42,
    true="Beauty",
    [function() return 17 end] = function() return 42 end,
    [math.pi] = "pi",
    [ {} ] = {},
    12, 11, 10, 9, 8
}

Es hat eine String-Schlüssel, einen boolean Schlüssel, eine Funktionstaste, einen nicht-ganzzahligen Schlüssel, einen Tabellenschlüssel und fünf Integer-Schlüssel. Sollte die Funktion Art vor der Zeichenfolge? Wie beurteilen Sie die Zeichenfolge in eine Zahl vergleichen? Wo sollte die Tabelle sortieren? Und was ist userdata und thread Werte, die nicht passieren in dieser Tabelle angezeigt werden?

Nach Konvention durch aufeinanderfolgende ganze Zahlen indizierten Werte mit 1 beginnen, werden als Listen verwendet. Mehrere Funktionen und gemeinsame Idiome folgen dieser Konvention und table.sort ist ein Beispiel. Funktionen, die Listen arbeiten über in der Regel alle Werte ignorieren auf Schlüssel gespeichert, die nicht Teil der Liste sind. Auch hier table.sort ist ein Beispiel:. Es nur die Elemente sortiert, die an Schlüsseln gespeichert sind, der Teil der Liste ist

Ein weiteres Beispiel ist der # Operator. Für die oben stehende Tabelle ist #unsortable 5 weil unsortable[5] ~= nil und unsortable[6] == nil. Beachten Sie, dass der Wert an der numerischen Index math.pi gespeichert ist, nicht, obwohl pi gezählt ist zwischen 3 und 4, weil es nicht eine ganze Zahl ist. Weiterhin ist keine der anderen Nicht-ganzzahlige Schlüssel wird entweder gezählt. Dies bedeutet, dass eine einfache for-Schleife kann die gesamte Liste iterieren:

for i in 1,#unsortable do
    print(i,unsortable[i])
end

Das ist zwar oft geschrieben als

for i,v in ipairs(unsortable) do
    print(i,v)
end

Kurz gesagt, Lua Tabellen sind ungeordnete Sammlungen von Werten, die jeweils durch einen Schlüssel indiziert; aber es gibt eine spezielle Konvention für die sequentiellen ganzzahlige Schlüssel bei 1 beginnen.

Edit: Für den speziellen Fall von Nicht-Integral-Schlüssel mit einer geeigneten partiellen Ordnung, gibt es eine Behelfslösung einen separaten Indextabelle beinhaltet. Der beschriebene Inhalt von Tabellen, die von String-Werten verkeilt ist ein geeignetes Beispiel für diesen Trick.

Zuerst sammelt die Schlüssel in einer neuen Tabelle, in Form einer Liste. Das heißt, machen eine Tabelle von aufeinanderfolgenden ganzen Zahlen indiziert bei 1 mit Tasten als Werte beginnen und zu sortieren, dass. Dann verwendet diesen Index zu iterieren dem Originaltisch in der gewünschten Reihenfolge.

Zum Beispiel, hier ist foreachinorder(), die diese Technik über alle Werte einer Tabelle Iterierte verwendet, eine Funktion für jeden Schlüssel / Wert-Paar, in einer durch eine Vergleichsfunktion bestimmt aufrufen.

function foreachinorder(t, f, cmp)
    -- first extract a list of the keys from t
    local keys = {}
    for k,_ in pairs(t) do
        keys[#keys+1] = k
    end
    -- sort the keys according to the function cmp. If cmp
    -- is omitted, table.sort() defaults to the < operator
    table.sort(keys,cmp)
    -- finally, loop over the keys in sorted order, and operate
    -- on elements of t
    for _,k in ipairs(keys) do
        f(k,t[k])
    end
end

Es erstellt einen Index, sortiert sie mit table.sort() , dann Schleifen über jedes Element in dem sortierten Index und ruft die Funktion f für jedes. Die Funktion f ist der Schlüssel und Wert übergeben. Die Sortierreihenfolge wird durch eine optionale Vergleichsfunktion bestimmt, die an table.sort geben wird. Es ist mit zwei Elementen vergleichen (die Schlüssel auf den Tisch t in diesem Fall) genannt und muss true zurück, wenn der erste kleiner als der zweite ist. Wenn nicht angegeben, verwendet table.sort die eingebaute in < Operator.

Zum Beispiel, angesichts der folgenden Tabelle:

t1 = {
    a = 1,
    b = 2,
    c = 3,
}

dann foreachinorder(t1,print) druckt:

a    1
b    2
c    3

und foreachinorder(t1,print,function(a,b) return a>b end) druckt:

c    3
b    2
a    1

Weil sie keine Reihenfolge an erster Stelle. Es ist wie der Versuch, einen Müllsack voller Bananen zu sortieren.

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