Pregunta

Por qué no puedo usar la tabla.ordenar para ordenar tablas con índices asociativos?

¿Fue útil?

Solución

Sólo se puede ordenar tablas con claves de enteros consecutivos comenzando en 1, es decir, las listas. Si usted tiene otra tabla de pares clave-valor, puede hacer una lista de pares y la clase que:

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

Por supuesto, esto sólo es útil si usted proporciona un orden personalizado (lt), que espera como pares clave argumentos / valor.

Este tema se discute con mayor detalle en una pregunta relacionada sobre la clasificación tablas Lua .

Otros consejos

En general, Lua tablas son pura matrices asociativas.No es "natural" orden distinto al de la como un efecto secundario de la particular de la tabla hash implementación utilizada en la Lua núcleo.Esto tiene sentido debido a que los valores de cualquier Lua (tipo de datos distinto nil) puede ser utilizado tanto como claves y valores;pero sólo cadenas y números de cualquier tipo de sensato ordenar y, a continuación, sólo entre los valores de igual tipo.

Por ejemplo, cuál debería ser el orden de esta tabla:

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

Tiene una clave de la cadena, un booleano clave, una tecla de función, uno no integral clave, una clave de la tabla, y las cinco claves de enteros.Debe la función de ordenar por delante de la cuerda?¿Cómo se puede comparar la cadena de un número?Donde debe la tabla de la suerte?¿Y qué acerca de userdata y thread los valores que no aparecen en esta tabla?

Por convención, los valores indexados por secuenciales enteros comenzando por el 1, se utilizan comúnmente en forma de listas.Varias funciones comunes y modismos de seguir este convenio, y table.sort es un ejemplo.Las funciones que operan sobre las listas suelen ignorar los valores almacenados en las teclas que no son parte de la lista.De nuevo, table.sort es un ejemplo:ordena sólo aquellos elementos que se almacenan en las teclas que forman parte de la lista.

Otro ejemplo es el de # operador.De la tabla anterior, #unsortable es 5 porque unsortable[5] ~= nil y unsortable[6] == nil.Observe que el valor almacenado en el índice numérico de math.pi no se cuenta aún a pesar de que pi es entre 3 y 4 debido a que no es un entero.Además, ninguno de los otros no-entero teclas se cuentan bien.Esto significa que un simple bucle for puede iterar sobre la lista completa:

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

A pesar de que a menudo se escribe como

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

En resumen, Lua tablas están sin ordenar colecciones de valores, cada uno representado por una llave;pero hay una convención especial por entero secuencial claves a partir de las 1.

Editar: Para el caso especial de la no-integral teclas con un adecuado orden parcial, no es un trabajo que involucran alrededor de un índice de la tabla.El se describe el contenido de las tablas con llave por la cadena de valores es un ejemplo adecuado para este truco.

En primer lugar, recoger las llaves en una nueva tabla, en la forma de una lista.Es decir, hacer una tabla indexada por números enteros consecutivos a partir de la 1 con las teclas como los valores y ordenar que.A continuación, utilice el índice para recorrer la tabla original en el orden deseado.

Por ejemplo, aquí es foreachinorder(), que utiliza esta técnica para iterar sobre todos los valores de una tabla, se llama a una función para cada par clave/valor, en un orden determinado por una función de comparación.

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

Construye un índice, los ordena con table.sort(), a continuación, se repite a lo largo de cada elemento en la ordenada índice y llama a la función f para cada uno de ellos.La función f se pasa la clave y el valor.El orden es determinado por un facultativo función de comparación que se pasa a table.sort.Se llama con dos elementos a comparar (las llaves de la tabla t en este caso) y debe volver true si el primero es menor que el segundo.Si se omite, table.sort utiliza el incorporado en < operador.

Por ejemplo, dada la siguiente tabla:

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

entonces foreachinorder(t1,print) impresiones:

a    1
b    2
c    3

y foreachinorder(t1,print,function(a,b) return a>b end) impresiones:

c    3
b    2
a    1

Debido a que no tienen ningún orden en primer lugar. Es como tratar de resolver una bolsa de basura llena de plátanos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top