簡體   English   中英

如何按值對 Perl hash 進行排序並相應地對鍵進行排序(可能在兩個 arrays 中)?

[英]How can I sort a Perl hash on values and order the keys correspondingly (in two arrays maybe)?

在 Perl 中,我想按值對 hash 的鍵進行排序,數字:

{
  five => 5
  ten => 10
  one => 1
  four => 4
}

生產兩個 arrays:

(1,4,5,10) and (one, four, five, ten)

然后我想規范化值數組,使數字是連續的:

(1,2,3,4)

我該怎么做呢?

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

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

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

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

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 Transform 來緩存計算結果。

如果我們想按哈希值排序,我們使用哈希鍵來查找它。 我們仍然得到一個鍵列表,但這次它們是按它們的值排序的。

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

從那里我們可以變得更復雜。 如果哈希值相同,我們可以對哈希鍵進行二次排序。

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

請參閱 Perl 常見問題條目,標題為“ 我如何對散列進行排序(可以選擇按值而不是鍵) ”。

您還可以使用perldoc -q在您的機器上本地搜索常見問題解答,如perldoc -q sort ,這就是我找到您的答案的方式。

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

有時最好是展示而不是告訴...

%results = (Paul=>87, Ringo=>93, John=>91, George=>97);

#display the results in ascending key (alphabetical) order
print "key ascending...\n";
foreach $key ( sort { $a cmp $b } keys %results ){
    print "$key=>$results{$key}\n";
}

print "\n";

# display the results in descending key (alphabetical) order
print "key descending...\n";
foreach $key ( sort { $b cmp $a } keys %results ){
    print "$key=>$results{$key}\n";
}

print "\n";

# display the results in descending value (numerical) order
print "value ascending...\n";
foreach $key ( sort { $results{$a} <=> $results{$b} } keys %results ){
    print "$key=>$results{$key}\n";
}

print "\n";

# display the results in ascending value (numerical) order
print "value descending...\n";
foreach $key ( sort { $results{$b} <=> $results{$a} } keys %results ){
    print "$key=>$results{$key}\n";
}

暫無
暫無

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

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