2009-04-13 74 views
5

我想排序一個散列實際上有一個散列作爲一個值。例如:如何通過Perl中的鍵對散列哈希進行排序?

my %hash1=(
    field1=>"", 
    field2=>"", 
    count=>0, 
); 
my %hash2; 
$hash2{"asd"}={%hash1}; 

,我插入大量的哈希以%hash2%hash2不同的計數值。

如何根據計數值hash1%hash1進行排序?

有沒有辦法做到這一點,而不手動執行quicksort,例如與Perl的排序功能?

+0

你的意思是你想通過從HASH2的值數排序的哈希值(如HASH1)的名單? – Jagmal 2009-04-13 06:24:31

+0

是Jagmal,這意味着我想對$ hash2 {「asd」} {count}進行排序。 – systemsfault 2009-04-13 06:29:26

回答

10
my @hash1s = sort {$a->{count} <=> $b->{count}} values %hash2; 
+0

我試過這種方式,但得到以下警告: [警告]:在數值比較中使用未初始化的值(<=>) – systemsfault 2009-04-13 06:48:13

+0

我的答案和我的評論答案的代碼段在測試時適用於我即使使用-w和「use strict」)。 – 2009-04-13 07:01:15

+0

由於一個或多個哈希值對'count'鍵沒有任何價值,所以您會收到該警告。如果你想把它們計爲0,你可以對{($ a - > {count} || 0)進行排序<=>($ b - > {count} || 0)} values%hash2; – nohat 2009-04-13 07:04:23

1

如果你想通過從HASH2的值數排序的哈希值(如HASH1)的列表中,這可能會幫助:

@sorted_hash1_list = sort sort_hash_by_count_key($a, $b) (values (%hash2); 


# This method can have any logic you want 
sub sort_hash_by_count_key { 
    my ($a, $b) = @_; 
    return $a->{count} <=> $b->{count}; 
} 
0

對於很多的情況下是如何排序的作品見http://perldoc.perl.org/functions/sort.html在Perl中。

這裏是一個例子..試圖讀取,而不是完美。

#!/usr/bin/perl 
# Sort Hash of Hashes by sub-hash's element count. 
use warnings; 
use strict; 


my $hash= { 
      A=>{C=>"D",0=>"r",T=>"q"} 
      ,B=>{} 
      ,C=>{E=>"F",G=>"H"} 
      }; 

sub compareHashKeys {0+(keys %{$hash->{$a}}) <=> 0+(keys %{$hash->{$b}}) } 

my @SortedKeys = sort compareHashKeys keys %{$hash}; 
print join ("," , @SortedKeys) ."\n"; 
6

perlfaq4,答案"http://faq.perl.org/perlfaq4.html#How_do_I_sort_a_hash"有你最需要的放在一起你的代碼的信息。

你可能也想看看排序的章節學習Perl

克里斯有一個完全正確的答案,雖然我討厭使用values這樣的。一個更熟悉的方式做同樣的事情是要經過頂級哈希的密鑰,但排序第二級重點:

my @sorted_hashes = 
    sort { $hash2->{$a}{count} <=> $hash2->{$b}{count} } 
    keys %hash2; 

我做這種方式,因爲它是有點不太令人費解。


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

(貢獻的布萊恩d FOY)

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

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

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

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

例如,爲了讓我們的報表順序不區分大小寫,我們在雙引號字符串中使用\ L序列使所有內容都爲小寫。 sort()塊然後比較小寫的值以確定按照何種順序放置鍵。

my @keys = sort { "\L$a" cmp "\L$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; 
0

要按數字排序使用< =>併爲字符串使用cmp。

# sort by the numeric count field on inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) { 
    print $key,$hash2{$key}->{'count'},"\n"; 
} 

# sort by the string field1 (or field2) on the inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) { 
    print $key,$hash2{$key}->{'field1'},"\n"; 
} 

反序簡單地交換$ a和$ b:

# sort by the numeric count field on inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) { 
    print $key,$hash2{$key}->{'count'},"\n"; 
} 

# sort by the string field1 (or field2) on the inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) { 
    print $key,$hash2{$key}->{'field1'},"\n"; 
} 
相關問題