in reply to Finding the size of a nested hash in a HoH

Maybe using 'each' is a more natural way to go through a hash:
while( my($key, $val) = each %{$rHoH_ProteinFamilies}){ my $size = (keys %{$val->{proteinfamily});

I suppose a more devious method to find the size of a hash is to use the equivalence between arrays and hashes:

my $size = @{[%$val->{proteinfamily}]}/2;

In other words you can think of hashes as arrays sliced up into sequential pairs, p1 & p2, where p1 = the key and p2 = the value. Hence the hash size will always be 1/2 the length of the array representation.

Replies are listed 'Best First'.
Re^2: Finding the size of a nested hash in a HoH
by BrowserUk (Patriarch) on Nov 10, 2011 at 16:21 UTC
    I suppose a more devious method to find the size of a hash

    Why would you use a "devious method", when scalar keys %{ $hashref } gives you it directly, without 1) iterating the entire hash; 2) contructing an array to hold the keys and values of the hash; 3) throwing away all that work and memory having only extracted a count; which you then have to divide by 2 anyway?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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.

      If each were removed from the language, would anyone really miss it? I know it'd break some legacy code, although I doubt I've used it more than once every few years. But is there ever a time when each saves more than a line of code over using keys and then getting the value in a second step? (Hmm, I'm off to search and see if there's already been a "what's the least useful core function" thread.)

      Aaron B.
      My Woefully Neglected Blog, where I occasionally mention Perl.

        . But is there ever a time when each saves more than a line of code over using keys and then getting the value in a second step?

        each really comes into its own when processing really large hashes.

        keys in a list context, such as a for loop:

        for my $key ( keys %hash ) { my $val = $hash{ $key }; ## ... }

        Creates a list of all the keys, which uses a substantial amount of memory and therefore time. Especially if it forces the process into swapping.

        Conversely, while each:

        while( my( $key, $val ) = each %hash ) { ## ... }

        Uses negligible extra memory and iterates far more quickly because of it.

        When operating with large hashes at the limits of memory, it can be the difference between seconds and hours of processing time.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        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.