wake-up-neo.com

Wie sortiere ich Perl-Hash nach Werten und ordne die Schlüssel entsprechend an (möglicherweise in zwei Arrays)?

In Perl möchte ich die Schlüssel eines Hashes numerisch nach Wert sortieren:

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

zwei Arrays erzeugen:

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

Und dann möchte ich das Wertearray so normalisieren, dass die Zahlen sequentiell sind:

(1,2,3,4)

Wie mache ich das?

23
Gogi

Sortieren Sie zuerst die Schlüssel nach dem zugehörigen Wert. Rufen Sie dann die Werte ab (z. B. mit einem Hash-Slice).

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

Oder wenn Sie eine Hash-Referenz haben.

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

Wie sortiere ich einen Hash (optional nach Wert anstelle von Schlüssel)?

Beginnen Sie mit den Schlüsseln, um einen Hash zu sortieren. In diesem Beispiel geben wir die Liste der Schlüssel für die Sortierfunktion an, die sie dann ASCII-betisch vergleicht (was möglicherweise durch Ihre Gebietsschemaeinstellungen beeinflusst wird). Die Ausgabeliste enthält die Schlüssel in ASCII-Reihenfolge. Sobald wir die Schlüssel haben, können wir sie durchgehen, um einen Bericht zu erstellen, der die Schlüssel in ASCII-Reihenfolge auflistet.

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

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

Im sort () -Block könnten wir allerdings etwas ausgefallener sein. Anstatt die Schlüssel zu vergleichen, können wir einen Wert mit ihnen berechnen und diesen Wert als Vergleich verwenden.

Um beispielsweise die Groß- und Kleinschreibung unserer Berichtsreihenfolge zu vermeiden, verwenden wir lc, um die Schlüssel vor dem Vergleich in Kleinbuchstaben zu setzen:

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

Hinweis: Wenn die Berechnung teuer ist oder der Hash viele Elemente enthält, sollten Sie sich die Schwartzsche Transformation ansehen, um die Berechnungsergebnisse zwischenzuspeichern.

Wenn wir stattdessen nach dem Hash-Wert sortieren möchten, verwenden wir den Hash-Schlüssel, um ihn nachzuschlagen. Wir bekommen immer noch eine Liste mit Schlüsseln, aber dieses Mal sind sie nach ihrem Wert sortiert.

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

Von dort können wir komplexer werden. Wenn die Hash-Werte gleich sind, können wir eine sekundäre Sortierung für den Hash-Schlüssel bereitstellen.

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

Bitte lesen Sie den Perl FAQ Eintrag mit dem Titel "Wie sortiere ich einen Hash (optional nach Wert anstelle von Schlüssel)"

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

Sie können auch perldoc -q, um FAQ lokal auf Ihrem Computer zu suchen, wie in perldoc -q sort, so habe ich deine Antwort gefunden.

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