Domanda

Perché non posso usare la tabella.ordina per ordinare le tabelle con indici associativi?

È stato utile?

Soluzione

È possibile ordinare solo tabelle con chiavi interi consecutivi da 1, cioè, liste. Se si dispone di un'altra tabella di coppie chiave-valore, si può fare una lista di coppie e ordinare che:

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

Naturalmente questo è utile solo se si fornisce un ordinamento personalizzato (lt), che prevede come argomenti coppie chiave / valore.

Questo problema è discusso più ampiamente in una domanda relativa sull'ordinamento tavoli Lua .

Altri suggerimenti

In generale, Lua tabelle sono pure gli array associativi.Non c'è "naturale" ordine diverso, come un effetto collaterale di una particolare tabella di hash attuazione utilizzato in Lua core.Questo ha senso perché i valori di tutti i Lua tipo di dati (oltre nil) possono essere utilizzati come chiavi e valori;ma solo stringhe e numeri di qualsiasi tipo di sensato ordine, e quindi solo tra i valori di tipo.

Per esempio, cosa si deve l'ordinamento di questa tabella:

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

Ha uno string key, uno booleano tasto, una funzione chiave, non integrale chiave, una chiave della tabella, e cinque chiavi integer.Qualora la funzione di ordinamento avanti la stringa?Come si fa a confrontare la stringa in un numero?Dove la tavola deve ordinare?E che dire di userdata e thread valori che non avvengono in questa tabella?

Per convenzione, i valori indicizzati da sequenziale numeri interi a partire da 1 sono comunemente usati come liste.Diverse funzioni di comuni e di frasi idiomatiche seguire questa convenzione, e table.sort ne è un esempio.Le funzioni che operano sulle liste di solito ignora i valori memorizzati chiavi che non fanno parte della lista.Di nuovo, table.sort ne è un esempio:ordina solo quegli elementi che sono conservati presso i tasti che fanno parte della lista.

Un altro esempio è l' # operatore.Per la tabella di cui sopra, #unsortable 5 perché unsortable[5] ~= nil e unsortable[6] == nil.Si noti che il valore memorizzato all'indice numerico math.pi non è contato, anche se pi è tra il 3 e il 4, perché non è un numero intero.Inoltre, nessuno degli altri valori non interi tasti sono conteggiato.Questo significa che un semplice ciclo for può scorrere l'intero elenco:

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

Se è vero che è spesso scritto come

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

In breve, Lua tabelle sono ordinato collezioni di valori, ogni indicizzata da un tasto;ma c'è una speciale convenzione per il numero intero sequenziale chiavi inizio a 1.

Edit: Per il caso di non integrale chiavi con un adeguato ordinamento parziale, c'è un work-around che coinvolgono un indice separato tabella.Il descritto il contenuto delle tabelle con la chiave da valori di stringa è un esempio giusto per questo trucco.

Primo, raccogliere le chiavi in una nuova tabella, in forma di elenco.Che è, una tabella indicizzata da numeri interi consecutivi a partire da 1 con chiavi e dei valori in genere che.Quindi, utilizzare l'indice per scorrere la tabella originale nell'ordine desiderato.

Per esempio, qui è foreachinorder(), che utilizza questa tecnica per scorrere tutti i valori di una tabella, chiamata a una funzione per ogni coppia chiave/valore, in un ordine determinato da una funzione di confronto.

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

Si costruisce un indice, ordina con table.sort(), poi loop su ogni elemento ordinato indice e chiama la funzione f per ciascuno di essi.La funzione f è passata la chiave e il valore.L'ordinamento è determinato da un opzionale funzione di confronto che è passato a table.sort.Viene chiamato con due elementi per confrontare (le chiavi della tabella t in questo caso), e deve restituire true se il primo è minore del secondo.Se omesso, table.sort utilizza il built-in < operatore.

Per esempio, data la seguente tabella:

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

quindi foreachinorder(t1,print) stampe:

a    1
b    2
c    3

e foreachinorder(t1,print,function(a,b) return a>b end) stampe:

c    3
b    2
a    1

Perché non hanno alcun ordine in primo luogo. E 'come cercare di risolvere un sacco della spazzatura pieno di banane.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top