簡體   English   中英

如何在Perl中按鍵對散列哈希值進行排序?

[英]How can I sort a hash of hashes by key in Perl?

我想對一個實際上有一個哈希作為值的哈希進行排序。 例如:

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

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

我如何排序%hash1根據計數值hash1

有沒有辦法在沒有手動實現快速排序的情況下執行此操作,例如使用Perl的sort函數?

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

perlfaq4開始“http://faq.perl.org/perlfaq4.html#How_do_I_sort_a_hash”的答案包含了將代碼組合在一起所需的大部分信息。

. 您可能還希望看到有關在排序的章節。

克里斯有一個完全正確的答案,雖然我討厭使用這樣的values 執行相同操作的更熟悉的方法是遍歷頂級哈希的鍵,但按二級鍵排序:

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

我是這樣做的,因為它不那么令人費解。


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

(由brian d foy提供)

要對哈希進行排序,請從鍵開始。 在這個例子中,我們給sort函數提供了一個鍵列表,然后用ASCII比較它們(這可能會受到你的語言環境設置的影響)。 輸出列表具有ASCIIbetical順序的鍵。 獲得密鑰后,我們可以通過它們創建一個報告,按ASCIIbetical順序列出密鑰。

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;

如果你想得到散列的列表(比如hash1),你可以從hash2中的值中按計數排序,這可能會有所幫助:

@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};
}

要按數字排序,請使用<=>和字符串使用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";
}

請參閱http://perldoc.perl.org/functions/sort.html以獲取有關Perl中排序如何工作的大量內容。

這是一個例子..試圖可讀,而不是perlish。

#!/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";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM