[英]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.