2010-01-10 24 views
18

Tengo una tabla de clave => valor que me gustaría ordenar en Lua. Las claves son todas enteros, pero no son consecutivas (y tienen significado). La única función de ordenación de Lua parece ser table.sort, que trata las tablas como matrices simples, descartando las claves originales y su asociación con elementos particulares. En cambio, esencialmente me gustaría poder usar la función PHP's asort().Ordenando asociativamente una tabla por valor en Lua

Lo que tengo:

items = { 
    [1004] = "foo", 
    [1234] = "bar", 
    [3188] = "baz", 
    [7007] = "quux", 
} 

Lo que quiero después de la operación de ordenación:

items = { 
    [1234] = "bar", 
    [3188] = "baz", 
    [1004] = "foo", 
    [7007] = "quux", 
} 

¿Alguna idea?

Editar: Sobre la base de las respuestas, voy a asumir que es simplemente un capricho impar de la intérprete de Lua incrustado particular, estoy trabajando con, pero en todas mis pruebas, pairs() siempre devuelve los elementos de la tabla en el orden en que fueron agregados a la mesa. (es decir, las dos declaraciones anteriores se repetirían de forma diferente).

Desafortunadamente, como no es un comportamiento normal, parece que no puedo obtener lo que necesito; Lua no tiene las herramientas necesarias integradas (por supuesto) y el entorno integrado es demasiado limitado para que yo pueda solucionarlo.

Aún así, gracias por su ayuda, ¡todo!

+7

Estas dos tablas son exactamente lo mismo. – lhf

Respuesta

35

Parece que no entiende bien algo. Lo que tienes aquí es un associative array. Las matrices asociativas no tienen un orden explícito en ellas, p. es solo la representación interna (generalmente ordenada) la que los ordena.

En resumen - en Lua, los dos arreglos que ha publicado son el mismo.

lo que cabe esperar en cambio, es una representación como:

items = { 
    {1004, "foo"}, 
    {1234, "bar"}, 
    {3188, "baz"}, 
    {7007, "quux"}, 
} 

Aunque no se puede conseguir mediante el índice de ahora (que se indexan 1, 2, 3, 4, pero se puede crear otra matriz de índice), puede ordenarlos usando table.sort.

Una función de clasificación sería entonces:

function compare(a,b) 
    return a[1] < b[1] 
end 

table.sort(items, compare) 
+1

Esto no parece ser cierto para Lua, según mis pruebas. Al iterar sobre una tabla usando 'pares()', la orden es estable y corresponde al orden en que se agregaron los elementos. Además, no tengo la opción de cambiar la forma en que se almacenan los datos; Estoy alimentando el resultado en una biblioteca de terceros que muestra los elementos al usuario en "' pairs() 'order". –

+2

Dudo que encuentre una forma de cambiar el orden - es un problema de representación ... –

+3

pares devuelve los datos en orden de almohadilla - puede ser estable - pero no es el orden en que se agregaron los elementos. De lua-users wiki "Tenga en cuenta que no hay garantía en cuanto al orden en que las claves se almacenarán en una tabla cuando se utilizan diccionarios, por lo que no se garantiza el orden de recuperación de las claves utilizando pares().Esta advertencia incluso se aplica a la parte indexada de la tabla, o en una tabla que no se usa como diccionario y tiene solo índices como claves. " – sylvanaar

1

lo hice una breve poco de Lua de codificación hace un par de años, pero ya no soy fluido en ella.

Cuando me enfrenté con un problema similar, copié mi matriz a otra matriz con las claves y los valores invertidos, luego usé sort en la nueva matriz.

No tenía conocimiento de la posibilidad de ordenar la matriz con el método que recomienda Kornel Kisielewicz.

6

hmm, se perdió la parte sobre no poder controlar la iteración. hay

Pero en lua siempre suele haber una manera.

http://lua-users.org/wiki/OrderedAssociativeTable

eso es un comienzo.Ahora necesitarías reemplazar los pares() que usa la biblioteca. Eso podría ser una simple como pairs = my_pairs. A continuación, puede utilizar la solución en el enlace de arriba

3

Las matrices PHP son diferentes de las tablas Lua.

  • matriz A PHP puede tener un lista ordenada de pares de clave y valor.

  • Una tabla Lua siempre contiene conjunto desordenado de pares clave-valor.

Una tabla Lua actúa como una matriz cuando un programador elige usar enteros 1, 2, 3, ... como teclas. La sintaxis del lenguaje y las funciones de biblioteca estándar, como table.sort, ofrecen soporte especial para tablas con claves de enteros consecutivos.

Por lo tanto, si desea emular una matriz de PHP, deberá representarla utilizando una lista de pares clave-valor, que en realidad es una tabla de tablas, pero es más útil pensar en ella como una lista de pares clave-valor. Pase una función personalizada "menos que" al table.sort y estará todo listo.

N.B. Lua le permite mezclar teclas de enteros consecutivos con cualquier otro tipo de claves en el misma tabla — y la representación es eficiente. A veces uso esta característica, generalmente para etiquetar una matriz con algunos fragmentos de metadatos.

3

Viniendo a esto unos meses más tarde, con la misma consulta. La respuesta recomendada parecía señalar la brecha entre lo que se requería y cómo se ve en LUA, pero no me consiguió exactamente lo que buscaba: - que fue un hash ordenado por Key.

Las primeras tres funciones de esta página DID sin embargo: http://lua-users.org/wiki/SortedIteration

+0

Pero ese es el problema opuesto: esta pregunta es ** ordenar por valor **. Su respuesta es ** ordenar por clave **. – bluenote10

7

Como dijo Komel, que está tratando con matrices asociativas, que no tienen garantiza el orden.

Si desea ordenar clave en base a su valor asociado al mismo tiempo preservar la funcionalidad de matriz asociativa, se puede hacer algo como esto:

function getKeysSortedByValue(tbl, sortFunction) 
    local keys = {} 
    for key in pairs(tbl) do 
    table.insert(keys, key) 
    end 

    table.sort(keys, function(a, b) 
    return sortFunction(tbl[a], tbl[b]) 
    end) 

    return keys 
end 

items = { 
    [1004] = "foo", 
    [1234] = "bar", 
    [3188] = "baz", 
    [7007] = "quux", 
} 

local sortedKeys = getKeysSortedByValue(items, function(a, b) return a < b end) 

sortedKeys es {} 1234,3188,1004,7007, y se puede acceder a sus datos, así:

for _, key in ipairs(sortedKeys) do 
    print(key, items[key]) 
end 

resultado:

1234  bar  
3188  baz  
1004  foo  
7007  quux  
+0

Usted acaba de salvar mi día, ha tenido problemas con los pedidos de una mesa como en los rangos de un juego por horas ahora. Ordenes sangrientas ... – Tosfera

Cuestiones relacionadas