in reply to Re: Pick any key from a very large hash
in thread Pick any key from a very large hash

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
  • Comment on Re^2: Pick any key from a very large hash

Replies are listed 'Best First'.
Re^3: Pick any key from a very large hash
by GrandFather (Saint) on Jul 11, 2009 at 23:21 UTC

    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