in reply to Pick any key from a very large hash

If you don’t want to use "keys", here is a fancy way to do it.
my %hash = ( a => 1, b => 2, c => 3, d => 4, e => 5, f => 6, g => 7, h => 8, i => 9, j => 10, ); my $hash_length = %hash; # To get actual length you would need 'scalar keys %hash' # But we are not using 'keys' here so lets get the length other way $hash_length =~ s{/.*}{}; foreach (1...10) { my $rand_num = rand $hash_length; # Make sure number is even. $rand_num = ($rand_num %2) ? ($rand_num - 1) : ($rand_num); my $key = (%hash)[$rand_num]; print "$_\t: $key\n"; } # output # 1 : e # 2 : d # 3 : c # 4 : j # 5 : a # 6 : e # 7 : e # 8 : c # 9 : j # 10 : e
Regards,
Ashish

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

    OP's concern was not the use of keys, but the potential cost of using it due to a perceived 'temporary array'. However various solutions to that problem have been suggested. Let's see how yours stacks up:

    use strict; use warnings; use Benchmark qw(cmpthese); my %bigHash = map {$_ => undef} 1 .. 1e3; my ($key) = each %bigHash; my $count = keys %bigHash; my ($key2) = (%bigHash)[0]; print "First key '$key', second '$key2'\n"; cmpthese ( -1, { byEach => sub {scalar keys %bigHash; my ($key) = each %bigHas +h;}, byArray => sub {my $key = (%bigHash)[0]}, } );

    Prints:

    First key '559', second '559' Rate byArray byEach byArray 5228/s -- -100% byEach 2414187/s 46082% --

    It's that 'temporary array' OP was worried about. A fancy solution no doubt but, for saving time, not a good one.


    True laziness is hard work
      I jumped in without giving it a thought and missed the real problem. I do agree it wouldn’t be efficient therefore won’t solve the purpose.
      I guess I gotta give some time before jumping in.
      Regards,
      Ashish
Re^2: Pick any key from a very large hash
by FloydATC (Deacon) on Jul 12, 2009 at 06:50 UTC
    Still, it's a creative solution to the problem, and within the original domain. I'm sure this technique can be helpful when dealing with a big native hash and not a DB_File.

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