2011-05-11 76 views
3

我有一個散列(在Perl中)其中的值都是數字。我需要創建另一個散列,其中包含來自第一個散列值的所有鍵/值對,其中值是所有值的最大值。返回最大值的所有哈希鍵/值對

例如,給定

my %hash = (
    key1 => 2, 
    key2 => 6, 
    key3 => 6, 
); 

我想創建一個包含一個新的哈希:

%hash_max = (
    key2 => 6, 
    key3 => 6, 
); 

我敢肯定有很多方法可以做到這一點,但我在尋找一個優雅解決方案(以及學習的機會!)。

回答

7
use List::Util 'max'; 
my $max = max(values %hash); 
my %hash_max = map { $hash{$_}==$max ? ($_, $max) :() } keys %hash; 

或者一個回合方法(類似於但從另一個答案略有不同):

my $max; 
my %hash_max; 
keys %hash; # reset iterator 
while (my ($key, $value) = each %hash) { 
    if (!defined $max || $value > $max) { 
     %hash_max =(); 
     $max = $value; 
    } 
    $hash_max{$key} = $value if $max == $value; 
} 
1

這使得一個傳過來的數據,但浪費了大量的哈希寫道:

use strict; 
use warnings; 

my %hash = (
    key1 => 2, 
    key2 => 6, 
    key3 => 6, 
); 

my %hash_max =(); 
my $max; 
foreach my $key (keys %hash) { 
     if (!defined($max) || $max < $hash{$key}) { 
       %hash_max =(); 
       $max = $hash{$key}; 
       $hash_max{$key} = $hash{$key}; 
     } 
     elsif ($max == $hash{$key}) { 
       $hash_max{$key} = $hash{$key}; 
     } 
} 

foreach my $key (keys %hash_max) { 
     print "$key\t$hash_max{$key}\n"; 
} 
1
# sort numerically descending 
my @topkey = sort {$hash{$b} <=> $hash{$a}} keys %hash; 

那麼最後的最大值後,頂部的值複製到%hash_max,具有循環終止:

for $key (@topkey) { 
    if ($hash{$key} == $hash{$topkey[0]}) { 
     $hash_max{$key} = $hash{$key} 
    } else { last } 
} 

ETA:注意不信那last使用,因爲在@topkey鍵進行排序,這樣我們就可以打破循環,當值不再像第一個。即以下所有值都較低。

+1

我真的不認爲你想要那裏'最後'。 – 2011-05-11 08:17:43

+1

@davorg你爲什麼這麼認爲? – TLP 2011-05-11 12:05:37