Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Pulling random elements from hash

by Anonymous Monk
on Jun 22, 2003 at 01:33 UTC ( [id://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?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-25 21:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found