There's more than one way to do things PerlMonks

### •Re: Random array sorting

by merlyn (Sage)
 on Sep 22, 2002 at 15:22 UTC ( #199905=note: print w/replies, xml ) Need Help??

in reply to Random array sorting

The answer's on your own hard drive, in the form of perldoc -q shuffle:
```Found in /opt/perl/snap/lib/5.8.0/pods/perlfaq4.pod
How do I shuffle an array randomly?
If you either have Perl 5.8.0 or later installed, or if yo
+u have
Scalar-List-Utils 1.03 or later installed, you can say:

use List::Util 'shuffle';

@shuffled = shuffle(@list);

If not, you can use a Fisher-Yates shuffle.

sub fisher_yates_shuffle {
my \$deck = shift;  # \$deck is a reference to an ar
+ray
my \$i = @\$deck;
while (\$i--) {
my \$j = int rand (\$i+1);
@\$deck[\$i,\$j] = @\$deck[\$j,\$i];
}
}

# shuffle my mpeg collection
#
my @mpeg = <audio/*/*.mp3>;
fisher_yates_shuffle( \@mpeg );    # randomize @mpeg i
+n place
print @mpeg;

Note that the above implementation shuffles an array in pl
+ace,
unlike the List::Util::shuffle() which takes a list and re
+turns
a new shuffled list.

You've probably seen shuffling algorithms that work using
splice, randomly picking another element to swap the curre
+nt
element with

srand;
@new = ();
@old = 1 .. 10;  # just a demo
while (@old) {
push(@new, splice(@old, rand @old, 1));
}

+do it
N times, you just invented a quadratic algorithm; that is,
O(N**2). This does not scale, although Perl is so efficien
+t that
you probably won't notice this until you have rather largi
+sh
arrays.

Replies are listed 'Best First'.
Re^2: Random array sorting
by bsoisoi on Dec 05, 2007 at 17:35 UTC
I have an even easier way.
my @array = ('one', 'two', 4, 5, 23242, 'all the candy in the universe', 'zebras');
print \$_, "\n" foreach (sort {int(rand(3))-1} @array);
Just makeup the -1, 0, 1 digits that \$a cmp \$b would return.
That's been shown time and time again to not be a "fair" shuffle, and in earlier Perl versions, would actually lose data or even core-dump. Bad. And yeah, I tried it in order to find that out.

Ignoring that it doesn't work, I don't see how

```print \$_, "\n" foreach (sort {int(rand(3))-1} @array);

is easier than

```print \$_, "\n" foreach shuffle @array;

Create A New User
Node Status?
node history
Node Type: note [id://199905]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2018-03-23 04:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
When I think of a mole I think of:

Results (287 votes). Check out past polls.

Notices?