我具有以下结构的存储的多维哈希(%info
):
$info{$os}{$id}=$length;
foreach $os (keys %info){
foreach $id (keys %{$info{$os}}){
print "$os $id => " . $info{$os}{$id} ."\n" if (keys %info > 100);
}
}
使用此方法,我可以读取哈希并仅打印出现次数超过100的那些$os
,但是现在我只想打印具有最大$ length(即值)的$id
。因此,我想按值对散列进行排序,并仅打印具有最高值的$os
和$id
。
有帮助吗?
可以使用List::Util::reduce获得每个顶级密钥中最大的密钥
use List::Util qw(reduce);
for my $os (keys %info) {
my $id_max_length = reduce {
$info{$os}{$a} > $info{$os}{$b} ? $a : $b
} keys %{$info{$os}};
say "$os --> $id_max_length --> $info{$os}{$id_max_length}";
}
要获得所有键中的最高值
my ($max_os, $max_id) =
map { $_->[0], $_->[1] }
reduce { $info{$a->[0]}{$a->[1]} > $info{$b->[0]}{$b->[1]} ? $a : $b }
map { [$_, max_id_for_os($_)] }
keys %info;
say "$max_os -> $max_id -> $info{$max_os}{$max_id}";
sub max_id_for_os {
my ($os) = @_;
reduce { $info{$os}{$a} > $info{$os}{$b} ? $a : $b } keys %{$info{$os}}
}
或者,也许更简单,在循环中对顶级键进行比较
my ($max_os, $max_id) = do { # initialize
my ($os) = keys %info;
$os, (keys %{$info{$os}})[0];
};
for my $os (keys %info) {
my $mid =
reduce { $info{$os}{$a} > $info{$os}{$b} ? $a : $b }
keys %{$info{$os}};
($max_os, $max_id) = ($os, $mid)
if $info{$os}{$mid} > $info{$max_os}{$max_id};
}
say "Largest: $max_os -> $max_id -> $info{$max_os}{$max_id}";
my($maxos,$maxid,$maxlength);
foreach my $os (sort keys %info) {
foreach my $id (keys %{ $info{$os} }) {
($maxos,$maxid,$maxlength) = ($os,$id,$info{$os}{$id})
if !defined $maxlength || $info{$os}{$id} > $maxlength;
}
}
print "$maxos $maxid => $maxlength\n";
有时最困难的事情就是准确地定义问题。尝试以下代码:
#!/usr/bin/perl
use warnings;
use strict;
use integer;
my %info = (
Debian => { jessie => 80, buster => 90, bullseye => 110 },
Fedora => { fedora_a => 70, fedora_b => 105 },
Arch => { arch_a => 50, arch_b => 108 },
Windows => { vista => 40, win10 => 63 },
OSX => { apple => 71 },
);
my @key_pairs_unsorted;
for my $os (keys %info) {
for my $id (keys %{$info{$os}}) {
push @key_pairs_unsorted, {os => $os, id => $id};
}
}
my @key_pairs_sorted =
sort { $info{$b->{os}}{$b->{id}} <=> $info{$a->{os}}{$a->{id}} }
@key_pairs_unsorted;
printf "%-7s %-8s %3d\n",
$_->{os}, $_->{id}, ${info}{$_->{os}}{$_->{id}}
for @key_pairs_sorted;
理解此代码应该可以帮助您精确地定义问题,然后您应该能够迅速地解决问题。
[作为进一步参考,可能需要关注this question或this one。