Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Pulling random elements from hash

by Anonymous Monk
on Jun 22, 2003 at 01:33 UTC ( #267894=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I'd like to be able to pull elements out of a hash table randomly (to create for example--flash cards). I know perl will pull out words in a particular order by using 'each' or 'keys' but the order will not change if the hash doesn't change. Any ideas? thanks, Michael

20030622 Edit by Corion: Changed title from "hash randomness"

Replies are listed 'Best First'.
Re: Pulling random elements from hash
by markjugg (Curate) on Jun 22, 2003 at 01:39 UTC
    my @values = values %hash; my $rand_value = $values[rand @values];

    Mark

Re: Pulling random elements from hash
by sgifford (Prior) on Jun 22, 2003 at 01:45 UTC
    You'd probably be better served by an array for this, where you could just do:
    $array[int(rand(scalar(@array)))];
    to choose a random element.

    You can do much the same thing, though, by pulling the hash keys into a list and choosing one randomly:

    $hk = (keys %hash)[int(rand(scalar(keys %hash)))]; $hv = $hash{$hk};
    If you'll do it often, pull the keys into an array and just use that:
    @arr = keys %hash; $hk = $arr[int(rand(scalar(@arr)))]; $hv = $hash{$hk};

    With both of the hash solutions, you end up with two copies of all the keys, so it's less memory-efficient than an array, but probably fine if you have a few thousand entries or less.

      $array[int(rand(scalar(@array)))];
      Of course you can just write
      $array[rand @array];
      which will do exactly the same thing and is a bit less distracting to read.

      Makeshifts last the longest.

        I saw that in another post. Do you know why this is? It seems like rand is unlikely to pick an integer, and $array[3.14159] seems nonsensical, but I tried it and it works...
Re: Pulling random elements from hash
by Aristotle (Chancellor) on Jun 22, 2003 at 02:03 UTC
    If you don't have a lot of pairs in the hash, the easiest way is probably
    my $random_card = (values %flash)[rand values %flash];

    Makeshifts last the longest.

Re: Pulling random elements from hash
by Jenda (Abbot) on Jun 22, 2003 at 19:04 UTC

    If I understand you right you do not want just a single random element. You want all elements, but just in a random order, right?

    If so you should have a look at Shuffle or List::Util::shuffle().

    Jenda
    Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
       -- Rick Osborne

    Edit by castaway: Closed small tag in signature

Re: Pulling random elements from hash
by George_Sherston (Vicar) on Jun 22, 2003 at 21:17 UTC
    Yet another way to do it:
    print $hash{$_} for (sort {rand() <=> 0.5} keys %hash)

    § George Sherston
      Perlfunc / sort: The comparison function is required to behave. If it returns inconsistent results (sometimes saying $x[1] is less than $x[2] and sometimes saying the opposite, for example) the results are not well-defined.

      I guess that means you don't really know what your code will give you. (Which kind of seems to be the point of it, but in another way. :))

      ihb
Re: Pulling random elements from hash
by YAFZ (Pilgrim) on Jun 23, 2003 at 10:37 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://267894]
Approved by markjugg
Front-paged by George_Sherston
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (1)
As of 2023-05-28 05:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?