I have a stored multidimensional hash (%info
) with the following structure:
$info{$os}{$id}=$length;
foreach $os (keys %info){
foreach $id (keys %{$info{$os}}){
print "$os $id => " . $info{$os}{$id} ."\n" if (keys %info > 100);
}
}
With this, I can read the hash and print only those $os
with more than 100 occurrences, but now I would like to print only the $id
with highest $length
(i.e., values). So I would like to sort the hash by values and print only $os
and $id
with highest value.
Can use List::Util::reduce to get the key with the largest value, within each top-level key
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}";
}
To get the highest value among all keys
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}}
}
Or, perhaps simpler, compare in the loop over top-level keys
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";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With