我有一个哈希(在Perl中),其中值都是数字。我需要创建另一个散列,其中包含来自第一个散列的所有键/值对,其中值是所有值的最大值。
例如,给定
my %hash = (
key1 => 2,
key2 => 6,
key3 => 6,
);
我想创建一个包含以下内容的新哈希:
%hash_max = (
key2 => 6,
key3 => 6,
);
我确信有很多方法可以做到这一点,但我正在寻找一个优雅的解决方案(并有机会学习!)。
答案 0 :(得分: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 :(得分: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";
}
答案 2 :(得分: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}}起作用,所以当值不再像第一个那样时,我们可以打破循环。即以下所有值都较低。