in reply to Pick any key from a very large hash

...each is meant for looping through the entire hash... - you're dead right - the hash is meant to be invariant over each - from each '...If you add or delete elements of a hash while you're iterating over it, you may get entries skipped or duplicated, so don't...'.

In answer to your question, again from each - '..it can be reset by reading all the elements from the hash, or by evaluating keys HASH or values HASH...'.

The moral of the story/posting is ... please RTFM before you post.

A user level that continues to overstate my experience :-))

Replies are listed 'Best First'.
Re^2: Pick any key from a very large hash
by FloydATC (Deacon) on Jul 11, 2009 at 22:36 UTC
    Hehe I did RTFM but you know what happens when you get stuck... you start trying creative stuff even if you know it might break things in funny ways :-)

    My theory was that maybe there was some obscure way to manually whack it back to zero. Guess not. Anyway, the problem is solved :-)

    -- Time flies when you don't know what you're doing

      I realise it's not an issue now, but it seems likely that calling keys in scalar context will reset the each iterator in (very small) constant time. Indeed a small test confirms this:

      use strict; use warnings; use Benchmark qw(cmpthese); my %bigHash = map {$_ => undef} 1 .. 1e3; my @resetEach = keys %bigHash; my ($key) = each %bigHash; my $count = keys %bigHash; my ($key2) = each %bigHash; print "First key '$key', second '$key2'\n"; cmpthese ( -1, { scalarKeys => sub {scalar keys %bigHash}, listKeys => sub {() = keys %bigHash}, } );

      Prints:

      First key '559', second '559' Rate listKeys scalarKeys listKeys 5184/s -- -100% scalarKeys 15969899/s 307964% --

      True laziness is hard work
        My original assumption was that keys would have to be called in a list context if I was to extract anything useful from it, and that calling it in scalar context would still cause a full traversal in order to count the key/value pairs.

        As usual, it turns out Perl is a bit more clever than expected, so using keys to reset and each to pick a pair may indeed be the Right Thingtm even for a huge hash. Maybe perldoc -f each should point this out more clearly?

        -- Time flies when you don't know what you're doing