2012-06-05 11 views

Antwort

45

Sortieren Sie zuerst die Schlüssel nach dem zugehörigen Wert. Dann hole die Werte (z. B. unter Verwendung eines Hash-Slices).

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

Oder wenn Sie eine Hash-Referenz.

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

Das war einfach. Manchmal ist es schwierig, diese netten Abkürzungen zu finden. Danke Ikegami. – Moni

+0

Sie können weitere Informationen in [Sortierfunktion in Perl] (http: // stackoverflow.com/fragen/6454744/sort-funktion-in-perl/6454804 # 6454804) –

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

Funktioniert es? Testet mit einem% h, hat aber nicht funktioniert. – Moni

+0

@Moni, es funktioniert ganz gut, so geschrieben wie es ist. Wenn Sie '% h' brauchen, dann sind es nur' keys% h' und '$ h {$ _}' in der Map. – Axeman

5

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

Um einen Hash zu sortieren, beginnen Sie mit den Tasten. In diesem Beispiel geben wir der Sortierfunktion eine Liste von Schlüsseln, die sie dann mit einem ASCII-Zeichen vergleicht (was möglicherweise von Ihren Gebietsschemaeinstellungen beeinflusst wird). Die Ausgabeliste hat die Schlüssel in ASCII-Reihenfolge. Sobald wir die Schlüssel haben, können wir sie durchlaufen, 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}; 
} 

Wir könnten mehr Phantasie im sort() Block obwohl. Anstatt die Schlüssel zu vergleichen, können wir einen Wert mit ihnen berechnen und diesen Wert als Vergleich verwenden.

Zum Beispiel unseres Bericht, um Groß- und Kleinschreibung zu machen, verwenden wir lc die Schlüssel in Kleinbuchstabe vor einem Vergleich:

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

Hinweis: Wenn die Berechnung teuer ist oder die Hash viele Elemente hat, können Sie möchte die Schwartzsche Transformation betrachten, um die Berechnungsergebnisse zwischenzuspeichern.

Wenn wir stattdessen nach dem Hash-Wert sortieren möchten, verwenden wir den Hash-Schlüssel, um nachzuschlagen. Wir bekommen immer noch eine Liste von Schlüsseln, aber diesmal 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 identisch 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; 
+2

Nit: 'lc ($ a) cmp lc ($ b)', die Sie auch als ' "\ L $ ein" cmp "\ L $ b"', wird nicht immer schrieb das Richtige zu tun. Sie wollen 'fc ($ a) cmp fc ($ b)' ('" \ F $ a "cmp" \ F $ b "'). Verfügbar seit 5.16. – ikegami

Verwandte Themen