2010-03-24 8 views
-2
@aoaoh; 

$aoaoh[0][0]{21} = 31; 
$aoaoh[0][0]{22} = 31; 
$aoaoh[0][0]{23} = 17; 

for $k (0 .. $#aoaoh) { 
    for $i(0.. $#aoaoh) { 
     for $val (keys %{$aoaoh[$i][$k]}) { 
      print "$val=$aoaoh[$i][$k]{$val}\n"; 
     } 
    } 
} 

La sortie est:Comment trier un tableau Perl de tableau de hachages?

 
    22=31 
    21=31 
    23=17 

mais je pensais que ce serait

 
    21=31 
    22=31 
    23=17 

S'il vous plaît me dire où est-ce mal.

Aussi comment puis-je trier les valeurs pour que je sois la sortie comme

 
    23=17 
    22=31 
    21=31 (if 2 keys have same value then key with higher value come first) 
+7

'use strict;' - s'il vous plaît! –

Répondre

1

Sons comme vous voulez:

for $val (sort keys %{$aoaoh[$i][$k]}) { 

et:

for $val (reverse sort keys %{$aoaoh[$i][$k]}) { 

Bien que de votre commentaire On dirait que vous ne voulez pas un tri inverse pur. Vous voulez créer votre propre fonction de tri:

for $val (sort {$aoaoh[$i][$k]->{$a} <=> $aoaoh[$i][$k]->{$b} || $a <=> $b} keys %{$aoaoh[$i][$k]}) { 
+2

Je pense que la deuxième moitié de sa question était comment trier par des valeurs, plutôt que des clés. C'était juste une coïncidence que c'était la même chose que l'ordre inverse. – Will

+0

oui .. Je vais avoir .. je veux trier sur les valeurs et puis si 2 valeurs puis trier ces 2 dans l'ordre décroissant ... – ksskr

+0

pourriez-vous s'il vous plaît dites-moi comment faire cela? – ksskr

0

On dirait que vous attendez hachages pour retourner leurs clés et des valeurs dans l'ordre défini, où il n'y a pas de garantie en Perl. Vous pouvez implémenter une structure de données plus complexe qui gère une partie de la commande pour vous, ou mettre plus de logique de tri dans votre affichage (au lieu de simplement boucler), ou charger un module pour prendre en charge des hachages ordonnés, tels que Tie::Hash::Indexed.

Je me attends Hash :: Indexé la mise en œuvre de la cravate pour ressembler à ceci:

my @aoaoh; 

use Tie::Hash::Indexed; 
tie my %hash, 'Tie::Hash::Indexed'; 
$aoaoh[0][0] = \%hash; 

$aoaoh[0][0]{21} = 31; 
$aoaoh[0][0]{22} = 31; 
$aoaoh[0][0]{23} = 17; 

for $k (0 .. $#aoaoh) { 
    for $i(0.. $#aoaoh) { 
     for $val (keys %{$aoaoh[$i][$k]}) { 
      print "$val=$aoaoh[$i][$k]{$val}\n"; 
     } 
    } 
} 
+0

J'ai un tableau de hachage .. Je veux que les hachages dans le tableau interne soient triés par leurs valeurs d'abord et quand les valeurs sont identiques, triées inversement par leurs clés .. – ksskr

+0

pour $ val (trier {$ aoaoh [ $ i] [$ k] -> {$ a} <=> $ aoaoh [$ i] [$ k] -> {$ b} || $ b <=> $ a} clés% {$ aoaoh [$ i] [$ k ]}) Solution d'Epsilon .. C'est ce que je veux .. mais je veux éviter les boucles alors qu'est-ce qu'une alternative pour cela ... – ksskr

0

Je lui ai répondu sur les deux autres mêmes questions de cet utilisateur, mais il semble que celui-ci va pour gagner donc je réponds ici aussi.

Réponse de perlfaq4 à How do I sort an array by anything?


Fourniture d'une fonction de comparaison pour faire un tri() (décrit dans le tri dans perlfunc):

@list = sort { $a <=> $b } @list; 

La fonction de tri par défaut est cmp, comparaison de chaînes, ce qui tri (1, 2, 10) en (1, 10, 2). < =>, utilisé ci-dessus, est l'opérateur de comparaison numérique.

Si vous avez besoin d'une fonction compliquée pour extraire la pièce que vous voulez trier, ne le faites pas dans la fonction de tri. Tirez-le d'abord, car le type BLOCK peut être appelé plusieurs fois pour le même élément. Voici un exemple de la façon de retirer le premier mot après le premier nombre sur chaque élément, puis de trier ces mots sans tenir compte de la casse.

@idx =(); 
for (@data) { 
    ($item) = /\d+\s*(\S+)/; 
    push @idx, uc($item); 
    } 
@sorted = @data[ sort { $idx[$a] cmp $idx[$b] } 0 .. $#idx ]; 

qui pourrait aussi être écrit de cette façon, en utilisant un truc qui est d'être connu comme Transformée Schwartzienne:

@sorted = map { $_->[0] } 
    sort { $a->[1] cmp $b->[1] } 
    map { [ $_, uc((/\d+\s*(\S+)/)[0]) ] } @data; 

Si vous devez trier sur plusieurs champs, le paradigme suivant est utile.

@sorted = sort { 
    field1($a) <=> field1($b) || 
    field2($a) cmp field2($b) || 
    field3($a) cmp field3($b) 
    } @data; 

Ceci peut être commodément combiné avec le précalcul des clés comme indiqué ci-dessus. Voir l'article de tri dans la collection «Bien plus que vous ne l'avez jamais voulu savoir» au http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz pour en savoir plus sur cette approche.

Voir aussi la question plus loin dans perlfaq4 sur les hachages de tri.

0

réponse pour Q1 sera:

print "${$aoaoh[0][0]}{$_}=$_\n" for sort keys %{$aoaoh[0][0]}; 

ce qui pourrait être écrit:

for (sort keys %{$aoaoh[0][0]}) { 
    print "${$aoaoh[0][0]}{$_}=$_\n" 
} 

Et la réponse pour Q2:

print "$_->[1]=$_->[0]\n" for 
map { [$_->[0], $_->[1]] } 
sort { $a->[0] cmp $b->[0] } 
map { [ ${$aoaoh[0][0]}{$_}, $_ ] } keys %{$aoaoh[0][0]};