perl_user123 has asked for the wisdom of the Perl Monks concerning the following question:

Hey Monks, I am trying to find the maximum of "values" in a hash. I have tried some methods already mentioned by perlmonks. But none of them happen to mention how to get the "key" for the maximum "value". Any help would be appreciated.

Replies are listed 'Best First'.
Re: max "value " of an hash
by BrowserUk (Patriarch) on Dec 21, 2010 at 09:39 UTC

    List::Util::reduce() is very useful for this:

    use List::Util qw[ shuffle reduce ];; my %hash; @hash{ 'a'..'z' } = shuffle 1 .. 26;; my $maxKey = reduce{ $hash{ $a } > $hash{ $b } ? $a : $b } keys %hash; +; print "$maxKey : ", $hash{ $maxKey };; x : 26

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Of course, List::Util also comes with max() and maxstr():

      #!perl use 5.010; use strict; use warnings; no warnings 'numeric'; # otherwise max() gives a warning on keys "a" and "b" my %hash = (a => 'value' , b => 'value', 0 => 'value', 1 => 'value'); # the values don't matter for this example use List::Util (qw/max maxstr/); my $max = max (keys %hash); my $maxstr = maxstr (keys %hash); say "numeric: $max\tstring: $maxstr";

      returns

      numeric: 1 string: b
Re: max "value " of an hash
by Utilitarian (Vicar) on Dec 21, 2010 at 09:08 UTC
    Code up something like this
    • set $max low
    • for each entry returned by values
    • while (my($key,$value) = each (%hash))
      • if $value is greater than the current value of max
        • set max to the $value
        • Set $max_key to key
    • Return the value of $max_key
    Edit: Misread the question
    print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
      # get values with numerical sort @values = sort {$a<=>$b} values %hash; # get the array last value, that considered the max value of the hash $max=$values[$#values]; print $max;
        You can find only one key from hash...
        Some time you can have situatuin like this:

        max value = 5
        but in hash present
        ${'asdf'}=5;
        ${'asdfg'}=5;

        This algorithm can show only last key or value...
Re: max "value " of an hash
by ELISHEVA (Prior) on Dec 21, 2010 at 09:47 UTC

    Just save both the key and the value each time you find a new maximum, instead of just the value. Something like this:

    # leave $vMax undefined initially so we don't need to # guess at the lowest value; this also lets us know we # never actually looked for a maximum on the off-chance # that our hash is empty my ($kMax,$vMax); while(my ($k,$v) = each(%someHash)) { # if this is the first key,value pair, initialize $kMax,$vMax # otherwise only reset on a new maximum if (!defined($vMax) || ($v > $vMax)) { $kMax = $k; $vMax = $v; } } if (!defined($vMax)) { print "No entries in my hash table!\n"; } else { print "key at maximum=$kMax, maximum value=$vMax\n"; }
Re: max "value " of an hash (list?)
by LanX (Saint) on Dec 21, 2010 at 10:36 UTC
    Shouldn't you better ask for the keys of a maximum value?

    UPDATE:

    Otherwise you can simply invert the hash with reverse to get the one and only corresponding key of a max value.

    The "best" solution depends on other criteria like time, memory or code complexity, which can only be specified by you...

    Cheers Rolf

Re: max "value " of an hash
by Anonymous Monk on Dec 21, 2010 at 09:21 UTC
    But none of them happen to mention how to get the "key" for the maximum "value"

    Easy, either you iterate by keys, or iterate by key/value with each, and you keep track of both the max value and its associated key