Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

min and max in a hash of hash

by nagalenoj (Friar)
on Jul 12, 2010 at 06:00 UTC ( #848928=perlquestion: print w/ replies, xml ) Need Help??
nagalenoj has asked for the wisdom of the Perl Monks concerning the following question:

I've a hash of hash like,
Year = { 2007 = { 01 => 07, 02 => 34, 10 => 24, 09 => 14, } 2008 = { 01 => 11, 02 => 64, 03 => 20, 09 => 13, } }
where I want to get the maximum and minimum of all years. So, result will be 02 in 2008 is maximum and 01 in 2007 is the minimum.
I've tried to get this in different ways. But, the code is larger like writing in conventional languages. Someone help me write this smarter.

Comment on min and max in a hash of hash
Download Code
Re: min and max in a hash of hash
by ikegami (Pope) on Jul 12, 2010 at 06:04 UTC
    use List::Util qw( min max ); my $max_y = max keys %Year; my $max_m = max keys %{ $Year{$max_y} }; my $min_y = min keys %Year; my $min_m = min keys %{ $Year{$min_y} };
      Hi ikegami, could you enlighten me what is wrong on using List::Util? the following code works fine, after I corrected the hash provided:
      foreach my $y (sort keys %Year) { my $min_y = List::Util::min values %{ $Year{$y} }; print "min of [$y] is [$min_y]\n"; }
      Edit: this works for sure only if you doesn't care about the month of the min/max value.

        That will give you the minimum value for each year. The OP wanted just the overall minimum. If he doesn't need the y/m of the minimum, then he could use

        use List::Util qw( min max ); my $min = min map { min values %{$Year{$_}} } keys %Year; my $max = max map { max values %{$Year{$_}} } keys %Year;

        Update: Fixed s/values/keys/ as per reply.

Re: min and max in a hash of hash
by ikegami (Pope) on Jul 12, 2010 at 06:12 UTC
    my ($max_y) = my ($min_y) = keys(%Year); my ($max_m) = my ($min_m) = keys(%{ $Year{$max_y} }); my $max = $Year{$max_y}{$max_m}; my $min = $Year{$min_y}{$min_m}; for my $y (keys(%Year)) { my $Month = $Year{$y}; for my $m (keys(%$Month)) { my $v = $Month->{$m}; if ($v < $min) { $min = $v; $min_y = $y; $min_m = $m; } elsif ($v > $max) { $max = $v; $max_y = $y; $max_m = $m; } } }

    Update: I was initialising $max_y twice instead of initialising $min_m. Fixed.

Re: min and max in a hash of hash
by Marshall (Prior) on Jul 12, 2010 at 09:32 UTC
    One way to do this is to transform the hash structure into an AoA so that it is easier to sort, then take first (index 0) and last (index -1) to get min and max. This type of approach allows easy reporting "ties" for min or max if that is important to you, eg maybe the minimum occurs on three different dates. Perl is very good at sorting and this runs faster than one might imagine.

    #!/usr/bin/perl -w use strict; use Data::Dumper; my %years =( 2007 => { '01' => 07, '02' => 34, '10' => 24, '09' => 14, }, 2008 => { '01' => 11, '02' => 64, '03' => 20, '09' => 13, }, ); my @year_data; foreach my $year (keys (%years)) { foreach my $month (keys %{$years{$year}}) { push (@year_data, [$year, $month, $years{$year}{$month}]); } } @year_data = sort { my ($yearA, $monthA, $dataA) = @$a; my ($yearB, $monthB, $dataB) = @$b; $dataA <=> $dataB or $monthA <=> $monthB or $yearA <=> $yearB }@year_data; print "minimum is: @{$year_data[0]}\n"; print "maximum is: @{$year_data[-1]}\n"; #minimum is: 2007 01 7 #maximum is: 2008 02 64
Re: min and max in a hash of hash
by AnomalousMonk (Abbot) on Jul 12, 2010 at 20:16 UTC
    ... 01 => 07, ...

    Just a note of caution: The number representation 07 (octal radix) has the same value for all radices in which '7' is a valid digit, e.g., 7 and 0x7; something like 077 has not. Don't tempt Fate.

    >perl -wMstrict -le "print 077" 63

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://848928]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (9)
As of 2014-12-29 13:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (188 votes), past polls