2011-05-11 157 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