in reply to Getting Max Value from Different Hashes

neversaint,
You should never resort to sorting to find the max or min value of a list unless the side effect of sorting has a benefit later on. Use a high or low water mark algorithm. Corion has suggested a fine one that, when possible, uses a C implementation that makes it really fast. Unfortunately - it doesn't completely answer your question since it only gives you the max value and not which hash it came from.

I question why you have 4 distinct hashes if each one only contains a single key. It seems to make more sense to have a single level hash or if absolutely necessary - a hash of hashes (HoH). For the moment, I will concede that there may be some valid, yet unspoken, reason to have things the way you do.

use List::Util 'max'; my @h_refs = ($hash_w, $hash_x, $hash_y, $hash_z); my ($max, $max_i); for ( 0 .. $#h_refs ) { my $max_v = max values %{ $h_refs[$_] }; if ( ! defined $max || $max_v > $max ) { ($max, $max_i) = ($max_v, $_); } } print "The max value is $max\n"; print "It is in the hash referenced by index $max_i\n";

Cheers - L~R

After re-reading the question for the 3rd time, I am not sure "which hash" is actually part of the question and was just an innoculous comment - *shrug*

Replies are listed 'Best First'.
Re^2: Getting Max Value from Different Hashes
by polettix (Vicar) on Aug 01, 2005 at 15:52 UTC
    Corion's solution solves the problem - the OP never talks about knowing where the winner value comes from, and his working-but-inefficient-and-inelegant (OP's words!) solution proves this IMHO. Maybe you got misleaded by his example:
    300 # from z

    Update: stroke fool observation. I'll read the whole answer next time :)

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
      frodo72,
      Perhaps you missed the bottom sentence where I stated that after re-reading the question 3 times I was no longer under the impression that the comment was anything more than a comment. It was small and an after-thought and easily missed.

      Cheers - L~R

        Yes, definitively. Sorry :)

        Flavio
        perl -ple'$_=reverse' <<<ti.xittelop@oivalf

        Don't fool yourself.
Re^2: Getting Max Value from Different Hashes
by neversaint (Deacon) on Aug 02, 2005 at 01:51 UTC
    Dear Limbic and all,
    You should never resort to sorting to find the max or min value of a list unless the side effect of sorting has a benefit later on.
    Thanks so much for those valuable insights. I am intrigued with your statement above. I wonder why it is so?

    Also this comment:
    ... when possible, uses a C implementation that makes it really fast
    I thought the built in sort function "is" implememented under "C" already? right?

    ---
    neversaint and everlastingly indebted.......
      You should never resort to sorting to find the max or min value of a list unless the side effect of sorting has a benefit later on.
      Thanks so much for those valuable insights. I am intrigued with your statement above. I wonder why it is so?
      Because sort has to find the order of all the elements, not just find the largest one. So if you've got 1000 items, it's spending all its time putting the 999 you don't care about in the right order. (Actually, it takes O(n log n) to sort a list, but only O(n) to find the maximal element using a simple scan.)
      ... when possible, uses a C implementation that makes it really fast
      I thought the built in sort function "is" implememented under "C" already? right?
      Well, yes, but if you specify a block to sort by, it has to go back into perl to call that on every pair of elements. IIRC, there are a few blocks that have been hardcoded ({$a <=> $b}, $b cmp $a, etc), but if all you care about is a single value, there's no point in sorting everything to get it.
      neversaint,
      Eimi Metamorphoumai has already done a great job of answering your question. I just wanted to try and make something clear as I made the poor mistake of assuming something would be obvious.

      Using a water mark algorithm is the best way of finding a max/min value in an unsorted list. List::Util provides such an algorithm that uses a C implementation when and where possible. This isn't comparing apples and apples since both are in C. One is doing far less work (as was pointed out by Eimi Metamorphoumai). So unless you need the values sorted for some other reason later on, don't use sort for this.

      Cheers - L~R