web-dev-qa-db-fra.com

Comment trier le hachage Perl sur les valeurs et ordonner les clés en conséquence (dans deux tableaux peut-être)?

En Perl, je veux trier les clés d'un hachage par valeur, numériquement:

{
  five => 5
  ten => 10
  one => 1
  four => 4
}

produire deux tableaux:

(1,4,5,10) and (one, four, five, ten)

Et puis je veux normaliser le tableau de valeurs de telle sorte que les nombres soient séquentiels:

(1,2,3,4)

Comment puis-je faire cela?

23
Gogi

Triez d'abord les clés selon la valeur associée. Obtenez ensuite les valeurs (par exemple en utilisant une tranche de hachage).

my @keys = sort { $h{$a} <=> $h{$b} } keys(%h);
my @vals = @h{@keys};

Ou si vous avez une référence de hachage.

my @keys = sort { $h->{$a} <=> $h->{$b} } keys(%$h);
my @vals = @{$h}{@keys};
51
ikegami

Comment trier un hachage (éventuellement par valeur au lieu de clé)?

Pour trier un hachage, commencez par les touches. Dans cet exemple, nous donnons la liste des clés à la fonction de tri qui les compare ensuite ASCIIbétiquement (ce qui pourrait être affecté par vos paramètres régionaux). La liste de sortie contient les clés dans l'ordre ASCIIbétique. Une fois que nous avons les clés, nous pouvons les parcourir pour créer un rapport qui répertorie les clés dans l'ordre ASCIIbétique.

my @keys = sort { $a cmp $b } keys %hash;

foreach my $key ( @keys ) {
    printf "%-20s %6d\n", $key, $hash{$key};
}

Nous pourrions obtenir plus de fantaisie dans le bloc sort (). Au lieu de comparer les clés, nous pouvons calculer une valeur avec elles et utiliser cette valeur comme comparaison.

Par exemple, pour rendre notre ordre de rapport insensible à la casse, nous utilisons lc pour mettre les clés en minuscules avant de les comparer:

my @keys = sort { lc $a cmp lc $b } keys %hash;

Remarque: si le calcul est coûteux ou que le hachage comporte de nombreux éléments, vous pouvez consulter la transformation Schwartzian pour mettre en cache les résultats du calcul.

Si nous voulons plutôt trier par valeur de hachage, nous utilisons la clé de hachage pour la rechercher. Nous obtenons toujours une liste de clés, mais cette fois, elles sont classées en fonction de leur valeur.

my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;

De là, nous pouvons devenir plus complexes. Si les valeurs de hachage sont les mêmes, nous pouvons fournir un tri secondaire sur la clé de hachage.

my @keys = sort {
$hash{$a} <=> $hash{$b}
or
"\L$a" cmp "\L$b"
} keys %hash;
5
Eric Leschinski

Veuillez consulter l'entrée Perl FAQ intitulée "Comment trier un hachage (éventuellement par valeur au lieu de clé)"

http://perldoc.Perl.org/perlfaq4.html#How-do-I-sort-a-hash-%28optionally-by-value-instead-of-key%29?

Vous pouvez aussi utiliser perldoc -q pour rechercher le FAQ localement sur votre machine, comme dans perldoc -q sort, c'est ainsi que j'ai trouvé votre réponse.

3
Andy Lester
my ( @nums, @words );
do { Push @nums,  shift @$_; 
     Push @words, shift @$_; 
   }
    foreach sort { $a->[0] <=> $b->[0] } 
            map  { [ $h->{ $_ }, $_ ] } keys %$h
   ;
2
Axeman