Asociativamente ordenando una tabla por valor en Lua

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 asort() PHP .

Lo que tengo:

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

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

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

¿Algunas ideas?

Editar: Basándome en las respuestas, voy a suponer que es simplemente una extraña peculiaridad del intérprete Lua incrustado en particular con el que estoy trabajando, pero en todas mis pruebas, los pairs() siempre devuelven los elementos de la tabla en el orden en que se agregaron a la mesa. (es decir, las dos declaraciones anteriores se repetirían de forma diferente).

Desafortunadamente, como ese 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 tu ayuda, ¡todo!

Parece que malinterpretas algo. Lo que tienes aquí es una matriz asociativa . Las matrices asociativas no tienen un orden explícito, por ejemplo, solo la representación interna (generalmente ordenada) las ordena.

En resumen: en Lua, los dos arreglos que publicaste son los mismos .

Lo que querrías, en cambio, es una representación tal:

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

Si bien no puede obtenerlos por índice ahora (están indexados 1, 2, 3, 4, pero puede crear otra matriz de índices), 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) 

Como dijo Komel, se trata de matrices asociativas, que no tienen orden garantizado.

Si desea ordenar claves en función de su valor asociado y, al mismo tiempo, preservar la funcionalidad de matriz asociativa, 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 puede acceder a sus datos de la siguiente manera:

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

resultado:

 1234 bar 3188 baz 1004 foo 7007 quux 

Hmm, se perdió la parte sobre no poder controlar la iteración. ahí

Pero en lua generalmente siempre hay un camino.

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. Luego puede usar la solución en el enlace de arriba

Las matrices PHP son diferentes de las tablas Lua.

  • Una matriz PHP puede tener una lista ordenada de pares clave-valor.

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

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

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 considerarla como una lista de pares clave-valor. . Pase una función personalizada “less-than” a table.sort y estará todo listo.

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

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.

Sin embargo, las primeras tres funciones en esta página DID: http://lua-users.org/wiki/SortedIteration

Hice un poco de encoding Lua hace un par de años pero ya no soy fluido.

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

No estaba al tanto de la posibilidad de ordenar la matriz con el método que recomienda Kornel Kisielewicz.

Intereting Posts