2012-06-05 69 views

回答

45

首先按相關值對鍵進行排序。然後獲取值(例如,通過使用散列片)。

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

或者如果你有一個散列引用。

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

這很容易。有時很難想出這些漂亮的快捷方式。謝謝ikegami。 – Moni

+0

你可以在[Perl中的排序函數]中看到更多信息(http:// stackoverflow。com/questions/6454744/sort-function-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

它工作嗎? %h的Testet,但沒有工作。 – Moni

+0

@Moni,它工作得很好,寫的是它的樣子。如果你需要'%h',那麼它只是'鍵%h'和'$ h {$ _}'在地圖中。 – Axeman

5

如何對散列進行排序(可選擇按值而不是鍵)?

要對散列進行排序,請從鍵開始。在這個例子中,我們給出了排序函數的關鍵字列表,然後將它們用ASCIIbet進行比較(這可能會受到您的語言環境設置的影響)。輸出列表具有按ASCII順序排列的鍵。一旦我們擁有了密鑰,我們就可以通過它們來創建一個報告,按ASCII順序列出密鑰。

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

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

雖然我們可以在sort()塊中獲得更多的花式。我們可以用它們計算一個值,並將該值用作比較,而不是比較鍵。

例如,爲了使我們的報告順序不區分大小寫,我們使用LC比較之前爲小寫字母鍵:

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

注:如果計算是昂貴或哈希有很多元素,可以希望查看Schwartzian變換來緩存計算結果。

如果我們想用散列值進行排序,我們使用散列鍵來查找它。我們仍然拿出一個鍵列表,但這次他們按照它們的價值排序。

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

從那裏我們可以變得更加複雜。如果散列值相同,我們可以在散列鍵上提供第二排序。

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

Nit:'lc($ a)cmp lc($ b)',你也寫成'「\ L $ a」cmp「\ L $ b」',並不總是做正確的事情。你想要'fc($ a)cmp fc($ b)'('「\ F $ a」cmp「\ F $ b」')。自5.16起可用。 – ikegami

相關問題