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

I'm in the proccess of writing a short cgi script and am looking for a little help. I need to be able to pick 5 random elements out of an ever growing array and all 5 have to be differnt elements from the array. Is there a simple way to do this? The only way I can come up with is painfully similar to a bubble sort and I really don't want to have to do all that coding. Thanks in advance
  • Comment on picking multiple random elements out of an array

Replies are listed 'Best First'.
Re: picking multiple random elements out of an array
by Masem (Monsignor) on Feb 04, 2002 at 02:27 UTC
    There's several different ways I can think of:
    • Use Algorithm::Shuffle to randomly shuffle the list, then grab the first 5 items from it. If you are removing items from the list, and don't care about order, and doing this often, this might be the best way, but will be slow with a very large array.
    • Generate a random number from 0 to the size of your array. Splice out that item from the array. Repeat 4 more times.
    • Variation of either of the above if you want to keep your array intact is to use a new array , (0..scalar @array-1) as the array to modify; once you have your items from here, treat these as indices to your main array.

    Dr. Michael K. Neylon - || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

      Here's a "variation of the above" code fragment from an ancient script. It produces a set of numbers which can be used as indices in an array slice.
      # @indices = randomsubset(scalar @array, $size_of_subset); sub randomsubset { my @indices = 0 .. $_[0] - 1; my @subset = (); push @subset, splice(@d, int rand @indices, 1) for 1 .. @_[1]; @subset; } print join (" ", randomsubset(50,5)), "\n";
      (The overly specific name indicates sloppy thinking on my part, for which I plead guilty.)

      IIRC, there's something equivalent in the Cookbook.

      The shuffle will work well, I never thought of that. The other was what I was trying to avoid because I didn't want to have to check for duplicates.
Re: picking multiple random elements out of an array
by chipmunk (Parson) on Feb 04, 2002 at 07:05 UTC
    Here's an extension of the FAQ's method for selecting a random line from a file. This one selects multiple lines/entries. It keeps the selected entries in their original order.
    my $count = 5; my @select; my $i = 0; for (@array) { push @select, $_ if rand() < ($count / ++$i); if (@select > $count) { splice(@select, rand($#select), 1); } }
(cLive ;-) Re: picking multiple random elements out of an array
by cLive ;-) (Prior) on Feb 04, 2002 at 03:22 UTC
    Sometimes, typing random array in the search box can be useful.

    cLive ;-)

Re: picking multiple random elements out of an array
by I0 (Priest) on Feb 05, 2002 at 01:30 UTC
    for(1..5){ my $r = rand @array; push @subset,$array[$r]; $array[$r] = $array[-1]; pop @array; }