Associativamente classificar uma tabela por valor em Lua
Pergunta
Eu tenho uma chave => tabela de valores que eu gostaria de classificar em Lua. As teclas são todos os inteiros, mas não são consecutivos (e têm significado). único tipo de função da Lua parece ser table.sort
, que trata mesas como matrizes simples, descartando as chaves originais e sua associação com itens específicos. Em vez disso, eu tinha essencialmente como ser capaz de usar a função asort()
do PHP.
O que eu tenho:
items = {
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
}
O que eu quero após a operação de classificação:
items = {
[1234] = "bar",
[3188] = "baz",
[1004] = "foo",
[7007] = "quux",
}
Todas as idéias?
Editar: Com base nas respostas, eu vou assumir que é simplesmente um capricho ímpar da Lua incorporado especial intérprete eu estou trabalhando com, mas em todos os meus testes, pairs()
sempre retorna itens da tabela na ordem em que foram adicionados à tabela. (Isto é, os dois acima declarações iria iterar de forma diferente).
Infelizmente, porque isso não é um comportamento normal, parece que eu não posso conseguir o que preciso; não Lua não tem as ferramentas necessárias built-in (é claro) e para o ambiente incorporado é demasiado limitado para mim trabalhar em torno dele.
Ainda assim, obrigado pela sua ajuda, tudo!
Solução
Você parece não entender alguma coisa. O que você tem aqui é um matriz associativa . As matrizes de associação tem a ordem não explícita sobre eles, por exemplo, é apenas a representação interna (geralmente classificadas) que as ordens deles.
Em suma - na Lua, ambas as matrizes que você postou são o mesmo
.O que você gostaria em vez disso, é tal representação a:
items = {
{1004, "foo"},
{1234, "bar"},
{3188, "baz"},
{7007, "quux"},
}
Enquanto você não pode obtê-los por índice agora (eles são indexados 1, 2, 3, 4, mas você pode criar outro array index), você pode classificá-los usando table.sort
.
A função de classificação seria então:
function compare(a,b)
return a[1] < b[1]
end
table.sort(items, compare)
Outras dicas
Como Komel disse, você está lidando com matrizes associativas, que não têm garantidos ordenação.
Se você quiser encomendar chave com base em seu valor associado ao mesmo tempo, preservar a funcionalidade de matriz associativa, você pode fazer algo como isto:
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 é {1234,3188,1004,7007}, e você pode acessar seus dados assim:
for _, key in ipairs(sortedKeys) do
print(key, items[key])
end
resultado:
1234 bar
3188 baz
1004 foo
7007 quux
hmm, perdi a parte sobre não ser capaz de controlar a iteração. há
Mas, na lua há geralmente sempre é um caminho.
http://lua-users.org/wiki/OrderedAssociativeTable
Isso é um começo. Agora você precisa substituir os pares () que usa a biblioteca. Isso poderia ser um simples como pares = my_pairs. Você poderia, então, usar a solução no link acima
matrizes PHP são diferentes das tabelas Lua.
-
array A PHP pode ter um lista ordenada de pares chave-valor.
-
tabela A Lua sempre contém um conjunto desordenado de pares chave-valor.
tabela A Lua age como uma matriz quando um programador escolhe usar inteiros 1, 2, 3, ... como chaves. A sintaxe da linguagem e funções da biblioteca padrão, como oferta table.sort
suporte especial para tabelas com chaves consecutivos inteiros.
Então, se você quiser emular um array PHP, você vai ter que representá-lo usando lista de pares chave-valor, que é realmente uma mesa de mesas, mas é mais útil pensar nisso como uma lista de chave pares -VALOR. Passe um costume "menos do que" função para table.sort
e você vai estar tudo pronto.
NB. Lua permite que você mix chaves consecutivos inteiros com quaisquer outros tipos de chaves no mesma de mesa ea representação é eficiente. Eu uso esse recurso, por vezes, geralmente para marcar uma matriz com alguns pedaços de metadados.
Chegando a este alguns meses mais tarde, com a mesma consulta. A resposta recomendada parecia identificar a diferença entre o que era necessário e como isso parece em LUA, mas não me que eu estava depois exatamente: -. Que era um Hash classificado por Key
As três primeiras funções nesta página DID no entanto: http://lua-users.org/wiki/ SortedIteration
Eu fiz uma breve pouco de Lua codificação de um par de anos atrás, mas eu não sou fluente na mesma.
Quando confrontados com um problema semelhante, eu copiei a minha matriz para outra matriz com chaves e valores invertida, então usado sort
na nova matriz.
Eu não estava ciente da possibilidade de classificar a matriz usando o método kornel kisielewicz recomenda.