2010-03-16 15 views
16

J'ai un tableau associatif en awk qui obtient peuplé comme ceci:Trie un tableau associatif dans awk

chr_count[$3]++ 

Lorsque je tente d'imprimer mon chr_counts, j'utilise ceci:

for (i in chr_count) { 
    print i,":",chr_count[i]; 
} 

Mais pas étonnamment, l'ordre de i n'est pas trié de quelque façon que ce soit. Existe-t-il un moyen facile d'itérer sur les touches triées de chr_count?

+2

Voir http://stackoverflow.com/a/5345056/69663 - si vous avez gawk 4, 'PROCINFO [" sorted_in "] =" @val_num_asc "' etc. sont très simples à utiliser. Le manuel montre beaucoup d'options différentes si vous voulez décroissant/ascendant, par valeur/clé, numériquement/par chaîne, votre propre fonction, etc.: https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning – unhammer

Répondre

22

Au lieu de asort, utilisez asorti(source, destination) qui trie les indices dans un nouveau tableau et vous ne devez copier le tableau.

Ensuite, vous pouvez utiliser le tableau de destination comme pointeurs dans le tableau source.

Pour votre exemple, vous l'utiliser comme ceci:

n=asorti(chr_count, sorted) 
for (i=1; i<=n; i++) { 
     print sorted[i] " : " chr_count[sorted[i]] 
} 
+0

Wow, totalement oublié à ce sujet malgré la lecture dans les docs. C'est certainement la meilleure réponse. – Cascabel

+0

+1 Brillant! –

+1

'asorti' ne fonctionne pas avec nawk-20121220-2.fc20.x86_64. –

4

Il est récupéré directement à partir the documentation:

populate the array data 
# copy indices 
j = 1 
for (i in data) { 
    ind[j] = i # index value becomes element value 
    j++ 
} 
n = asort(ind) # index values are now sorted 
for (i = 1; i <= n; i++) { 
    do something with ind[i]   Work with sorted indices directly 
    ... 
    do something with data[ind[i]]  Access original array via sorted indices 
} 
+0

Attention, cette solution est défectueuse car cela finit par perdre les clés qui ont les mêmes valeurs dans le tableau d'origine. La solution acceptée par cet autre thread a une idée sur la façon de contourner ce problème: http://stackoverflow.com/a/5345056/95750 – haridsv

+1

@haridsv Non, je ne le pense pas.Cette question concerne le tri par les clés, pas les valeurs, et il ne peut y avoir deux valeurs pour la même clé, donc il n'y a pas de problème ici. L'autre question à laquelle vous faites référence concerne le tri par valeurs (qui, en effet, peuvent ne pas toutes être distinctes), donc si vous avez essayé d'utiliser ce code pour cela, ce serait un problème. Mais ce n'est pas défectueux si vous l'utilisez pour ce qu'il est écrit. – Cascabel

+0

Excuses .. J'ai mal lu le code d'indexation comme "retournant" clé/valeurs, mais après la relecture, j'ai remarqué que vous utilisez un nombre sans cesse croissant comme index, pas la valeur d'origine. Merci d'être revenu et de l'avoir clarifié. – haridsv

6

Notez que asort() et asorti() sont spécifiques à gawk, et sont inconnus awk. Pour le plain awk, vous pouvez rouler le vôtre sort() ou en obtenir un d'ailleurs.

11

Vous pouvez utiliser la commande de tri. par exemple.

for (i in data) 
print i ":", data[i] | "sort" 
0

Je suis récemment tombé sur cette question et a constaté que je pouvais avec gawk définir la valeur de PROCINFO["sorted_in"] pour contrôler ordre d'itération. J'ai trouvé une liste de valeurs valides pour ce en recherchant Procinfo en ligne et atterris sur la page Guide de cette GNU Awk utilisateur: https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

Affiche la liste des options du formulaire @{key|val}_{num|type|str}_{asc|desc} avec:

  • key tri par clé et val tri par valeur.
  • num trier numériquement, str par chaîne et type par type affecté. Par ordre croissant et desc par ordre décroissant.

J'ai simplement utilisé:

PROCINFO["sorted_in"] = "@val_num_desc" 
for (i in map) print i, map[i] 

Et la sortie a été réglé dans l'ordre décroissant des valeurs.