Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Random array sorting

by kidd (Curate)
on Sep 22, 2002 at 15:10 UTC ( #199901=perlquestion: print w/replies, xml ) Need Help??
kidd has asked for the wisdom of the Perl Monks concerning the following question:


I want to know if there is a way in which I can randomnize(?) the content in an array.

In example:
Lets say I have this array with names:

my @array = ('uriel', 'daniel', 'joel', 'samuel');

Now what I want is create a process so every time I print the array it prints the names in different order.

I've already tried this without success because it returns a number:

#!/usr/bin/perl -w use strict; my @array = ('uriel', 'daniel', 'joel', 'samuel'); print "Array before random: @array\n\n"; my @n_array = rand(@array); print "Array after random: @n_array";

I thoght it might work but it doesnt. I hope someone could give me an idea to work this out...


Replies are listed 'Best First'.
•Re: Random array sorting
by merlyn (Sage) on Sep 22, 2002 at 15:22 UTC
    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)); } This is bad because splice is already O(N), and since you +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.

    -- Randal L. Schwartz, Perl hacker

      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;
Re: Random array sorting
by Aristotle (Chancellor) on Sep 22, 2002 at 15:15 UTC

    See merlyn's reply below.

    sub shuffle { my @shuffled; push @shuffed, splice(@_, rand(@_), 1) while @_; return @shuffled; } print shuffle @array;

    The splice pulls a random element out of the array, which is pushed onto the new array. Repeat while there are still elements in the list.

    Makeshifts last the longest.

Re: Random array sorting
by FloydATC (Chaplain) on Apr 03, 2013 at 10:30 UTC
    Before discovering List::Util I used this:
    sub shuffled { my @ordered = @_; my @shuffled = (); while (@ordered) { my $i = int(rand() * @ordered); push @shuffled, $ordered[$i]; splice(@ordered, $i, 1); } return @shuffled; } print join(",", shuffled(1,2,3,4,5)) . "\n";

    ...but I don't anymore.

    -- Time flies when you don't know what you're doing

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://199901]
Approved by Courage
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2017-01-23 00:30 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (190 votes). Check out past polls.