4.18. Randomizing an Array
4.18.1. Problem
You want to randomly shuffle the
elements of an array. The obvious application is writing a card game,
where you must shuffle a deck of cards, but it is equally applicable
to any situation where you want to treat elements of an array in a
random order.
4.18.2. Solution
Use the
shuffle function from the standard List::Util
module, which returns the elements of its input list in a random
order.
use List::Util qw(shuffle);
@array = shuffle(@array);
4.18.3. Discussion
Shuffling is a surprisingly tricky process. It''s easy to write a bad
shuffle:
sub naive_shuffle { # DON''T DO THIS
for (my $i = 0; $i < @_; $i++) {
my $j = int rand @_; # pick random element
($_[$i], $_[$j]) = ($_[$j], $_[$i]); # swap ''em
}
}
This algorithm is biased; the list''s possible permutations don''t all
have the same probability of being generated. The proof of this is
simple: take the case where we''re passed a three-element list. We
generate three random numbers, each of which can have three possible
values, yielding 27 possible outcomes. There are only six
permutations of the three-element list, though. Because 27 isn''t
evenly divisible by 6, some outcomes are more likely than others.The List::Util module''s shuffle function avoids
this bias to produce a more randomly shuffled result.If all you want to do is pick one random element from the array, use:
$value = $array[ int(rand(@array)) ];
4.18.4. See Also
The rand function in
perlfunc(1) and Chapter 29 of
Programming Perl; for more on random numbers,
see Recipe 2.6, Recipe 2.7, and Recipe 2.8; Recipe 4.20 provides another way to select a random
permutation