我试图找出散列中的最大值以及该最大值的相应键。我的哈希看起来像
%hash = (
bob => "4.9",
gita => "3.9 , 6.8",
diu => "3.0",
);
现在我想用它所属的键找到该哈希中的最大值。
所需的输出是
gita 6.8
我正在尝试按升序对%hash
中的值进行排序,以获得这样的最大值
sub hashValueAscendingNum {
$hash{$a} cmp $hash{$b};
}
foreach my $highest (sort hashValueAscendingNum(keys(%hash))) {
print "\t $hash{$highestMagnitude} \t\t $highest \n";
}
我希望检查哈希中的所有值,并且应该使用其键返回具有最大值的值。
我该怎么做?
答案 0 :(得分:1)
您需要先将每个密钥与原始%hash
中与其对应的最高值相关联,然后找到与最高值关联的密钥。
#!/usr/bin/env perl
use strict; use warnings;
use List::Util qw( max );
my %hash = (
bob => [ 4.9 ],
gita => [ 3.9, 6.8 ],
diu => [ 3.0 ],
);
my %max = map { $_ => max @{ $hash{$_} } } keys %hash;
my ($argmax) = (sort { $max{$b} <=> $max{$a} } keys %max)[0];
my $max = $max{ $argmax };
print join(' => ', $argmax, $max), "\n";
当然,这是非常低效的(尤其是使用sort
),但对于您展示的尺寸,这并不重要。为了完整起见,这是使用each
:
#!/usr/bin/env perl
use strict; use warnings;
use List::Util qw( max );
my %hash = (
bob => [ 4.9 ],
gita => [ 3.9, 6.8 ],
diu => [ 3.0 ],
);
my ($argmax, $max) = @{ init_argmax_max(\%hash) };
while (my ($k, $v) = each %hash) {
$v = max @{ $v };
if ( $v > $max ) {
$argmax = $k;
$max = $v;
}
}
print join(' => ', $argmax, $max), "\n";
sub init_argmax_max {
my ($hash) = @_;
my ($argmax, $max) = each %{ $hash };
keys %{ $hash };
$max = max @{ $max };
return [$argmax, $max];
}
答案 1 :(得分:1)
哈希只有一个密钥和一个值,每个密钥必须是唯一的。在你原来的问题中你有这个:
%hash = (
bob => "4.9",
gita =>"3.9 , 6,8",
diu => "3.0",
);
好吧,gita
不能有两个值。也不是,你的哈希中有两个键等于gita
。因此,您不能使用简单的哈希来存储您的值。
通过使用引用,可以解决这个问题。例如,哈希中的每个元素都可以包含reference to an array。因此,您的数据结构可能如下所示:
%hash = (
bob => [(4.9)],
gita => [(3.9, 6.8)],
diu => [(3.0)],
);
[
和]
标记对数组的引用。
但是,这并不能真正解决您的特定问题,因为您现在必须遍历散列中的每个键,然后是每个键的数组中的每个元素,并对它们进行排序。您可以创建一个排序子例程,但仅仅因为您可以说sort
不能使其有效。
也许你需要的是一个数组数组。这将消除gita
具有两个值的问题,但使排序更容易一些。想象一下这样的结构:
my @array = (
[bob => 4.9],
[gita => 3.9],
[gita => 6.8],
[diu => 3.0],
);
现在,我们可以根据@array
的值对$array[$x]->[1]
进行排序!我们所需要的只是数组@array
的每个元素都要将$ a-&gt; [1]与$ b-&gt; [1]进行比较。然后,如果我们对它进行反向排序,那么最大的元素将是$array[0]
。名称为$array[0]->[0]
,元素为$array->[0]->[1]
。
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say switch);
my @array = (
[bob => 4.9],
[gita => 3.9],
[gita => 6.8],
[diu => 3.0],
);
@array = reverse sort mysort @array;
say "$array[0]->[0] $array[0]->[1]";
sub mysort {
$a->[1] <=> $b->[1];
}
输出是:
gita 6.8.
您注意到Perldoc's perllol的链接?如果您之前从未使用过Perl参考资料,我建议您阅读。
答案 2 :(得分:0)
#!/usr/bin/perl
use warnings;
use strict;
my %hash = (
bob => [ 4.9 ],
gita => [ 3.9, 6.8 ],
diu => [ 3.0 ],
);
my $max_key;
my $max_val=0;
foreach my $key (keys %hash) {
foreach my $val ( @{$hash{$key}} ) {
($max_key, $max_val) = ($key, $val)
if $val > $max_val;
}
}
print "$max_key => $max_val\n";
答案 3 :(得分:0)
你有几个很好的答案。现在是一个坏的(假设您在哈希中修复小数分隔符):
my %hash = (bob => "4.9",
gita =>"3.9 , 6.8",
diu => "3.0",
);
my $max = (map{join" ",@$_[0,1]}sort{$b->[1]-$a->[1]}map{[$_,sort{$b-$a}split(/ , /,$hash{$_})]}keys%hash)[0];
print "$max\n";
输出:
gita 6.8
除非你故意试图打高尔夫球和/或混淆它,否则永远不要这样做。