Pourquoi je ne peux pas utiliser table.sort pour trier des tables avec des index associatifs?Impossible de trier les tables avec des index associatifs
Répondre
Vous ne pouvez trier les tables avec des clés entières consécutives à partir de 1, c'est-à-dire des listes. Si vous avez une autre table de paires clé-valeur, vous pouvez faire une liste de paires et trier 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
Bien sûr, cela est utile que si vous fournissez un ordre personnalisé (lt
) qui prévoit que les principaux arguments/paires de valeurs.
Ce problème est traité plus en détail dans related question about sorting Lua tables.
Parce qu'ils n'ont aucun ordre en premier lieu. C'est comme essayer de trier un sac à ordures rempli de bananes.
En fait, je pense que c'est plus comme essayer de trier un sac à dos plein de cœurs d'apple –
En général, les tables Lua sont des tableaux associatifs purs. Il n'y a pas d'ordre "naturel" autre que l'effet secondaire de l'implémentation particulière de la table de hachage utilisée dans le noyau de Lua. Cela est logique car les valeurs de tout type de données Lua (autre que nil
) peuvent être utilisées à la fois comme des clés et des valeurs; mais seules les cordes et les nombres ont une sorte d'ordre sensible, et seulement entre des valeurs de même type.
Par exemple, que si l'ordre de tri de cette table soit:
unsortable = {
answer=42,
true="Beauty",
[function() return 17 end] = function() return 42 end,
[math.pi] = "pi",
[ {} ] = {},
12, 11, 10, 9, 8
}
Il a une clé de chaîne, une clé booléenne, une touche de fonction, une touche non-intégrale, une clé de table, et cinq clés entières. La fonction devrait-elle trier en avant de la chaîne? Comment comparez-vous la chaîne à un nombre? Où devrait trier la table? Et qu'en est-il des valeurs userdata
et thread
qui n'apparaissent pas dans cette table? Par convention, les valeurs indexées par des entiers séquentiels commençant par 1 sont couramment utilisées en tant que listes. Plusieurs fonctions et idiomes communs suivent cette convention, et table.sort
en est un exemple. Les fonctions qui opèrent sur des listes ignorent généralement les valeurs stockées sur les clés qui ne font pas partie de la liste. Encore une fois, table.sort
est un exemple: il trie uniquement les éléments qui sont stockés sur les clés qui font partie de la liste. L'opérateur #
est un autre exemple. Pour le tableau ci-dessus, #unsortable
est 5 car unsortable[5] ~= nil
et unsortable[6] == nil
. Notez que la valeur stockée à l'index numérique math.pi
n'est pas prise en compte même si pi est compris entre 3 et 4 car ce n'est pas un nombre entier. De plus, aucune des autres clés non entières n'est comptée non plus. Cela signifie qu'une simple boucle peut parcourir la liste complète:
for i in 1,#unsortable do
print(i,unsortable[i])
end
Bien que ce soit souvent écrit
for i,v in ipairs(unsortable) do
print(i,v)
end
En bref, les tables Lua sont des collections non ordonnées de valeurs, indexées chacune par une clé ; mais il y a une convention spéciale pour les clés entières successives commençant à 1.
Edit: Pour le cas particulier des clés non solidaires d'un ordre partiel approprié, il y a un travail autour impliquant une table d'index séparé. Le contenu décrit des tables codées par des valeurs de chaîne est un exemple approprié pour cette astuce. Commencez par collecter les clés dans une nouvelle table, sous la forme d'une liste. C'est-à-dire, faites une table indexée par des entiers consécutifs commençant à 1 avec les clés comme valeurs et triez-la. Ensuite, utilisez cet index pour parcourir la table d'origine dans l'ordre souhaité.
Par exemple, voici foreachinorder()
, qui utilise cette technique pour parcourir toutes les valeurs d'une table, en appelant une fonction pour chaque paire clé/valeur, dans un ordre déterminé par une fonction de comparaison.
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
Elle construit un index, il trie avec table.sort()
, puis une boucle sur chaque élément de l'index trié et appelle la fonction f
pour chacun d'eux. La fonction f
reçoit la clé et la valeur. L'ordre de tri est déterminé par une fonction de comparaison optionnelle qui est transmise à table.sort
. Il est appelé avec deux éléments à comparer (les clés de la table t
dans ce cas) et doit renvoyer true
si le premier est inférieur au second. S'il est omis, table.sort
utilise l'opérateur <
intégré.
Par exemple, étant donné le tableau suivant:
t1 = {
a = 1,
b = 2,
c = 3,
}
puis foreachinorder(t1,print)
impressions:
a 1 b 2 c 3
et foreachinorder(t1,print,function(a,b) return a>b end)
impressions:
c 3 b 2 a 1
OK, comment puis-je trier alors? Après tout, je veux fournir ma propre fonction de comparaison, donc je ne sais pas pourquoi cela ne peut pas être fait. Tous les éléments de table ont le même modèle: key est une chaîne et value est une autre table. – mnn
Voir mon edit pour un exemple en utilisant une deuxième table pour le tri. – RBerteig
- 1. mysql btree index sur les tables InnoDB?
- 2. Impossible de supprimer les bordures des tables dans Word export
- 3. Utilisation de tableaux associatifs avec preg_replace
- 4. index Ajout à gerrund tables
- 5. Trier Hash Tables Glib - Qsort
- 6. PHP: Utiliser des espaces dans les indices de tableaux associatifs
- 7. Formulaire pour trier un index dans les rails
- 8. Comment trier les résultats d'une recherche lucene entre plusieurs index?
- 9. Comment trier Windows par z-index?
- 10. Requête personnalisée dans les vues drupal - maintenant impossible de trier
- 11. comment fonctionnent les index dans les tables mysql (MyISAM)?
- 12. Passer des tableaux associatifs dans call_user_func_array (...)
- 13. CanCan gem | impossible: index, utilisateur
- 14. SQL Server - Tables partitionnées et index clusterisé?
- 15. liste des tables sans index en SQL 2008
- 16. Récupérer des données de plusieurs tables et les trier toutes en fonction de leur temps
- 17. Retirer dupes/trier à partir d'un tableau de tableaux associatifs en PHP
- 18. Pourquoi les opérateurs sont-ils correctement associatifs dans CShell qui restent associatifs dans C?
- 19. Comment créer un index sur des tables différentes
- 20. mysql: boucle sur les tables et alter table ajouter index
- 21. Trier les numéros avec easy68k
- 22. mysqldump toutes les tables avec des données, avec des instructions create et add-drop tables
- 23. Utilisation de constantes comme indices pour les tableaux associatifs Javascript
- 24. listes à trier, avec des listes à trier
- 25. Impossible d'ajouter un index sur un champ avec InnoDB?
- 26. Tri basé sur des tableaux associatifs en D
- 27. Comment ajouter des index aux bases de données avec MigratorDotNet?
- 28. Informations sur les stides de cache associatifs à N-way
- 29. Impossible de savoir comment joindre ces tables
- 30. Tableaux associatifs en Javascript?
Donc vous dites tous les deux qu'il n'y a aucun moyen de trier une table avec des clés personnalisées (c'est-à-dire des chaînes de caractères) ??? J'ai vraiment aimé Lua, pour être un langage si flexible, mais même Java ou merdique (le meilleur lang. Jamais) C# peut le faire. – mnn
Les tables Lua avec des clés à cordes sont * non * commandées. Si vous voulez commander un ensemble de paires clé-valeur, vous modifiez la représentation. –
Mais je ne peux pas en obtenir un élément, car je dois enregistrer l'entier de l'entrée dans la table. Et cet index va changer après la suppression d'une entrée ... – mnn