Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

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 chanting in the Monastery: (5)
As of 2017-02-24 02:45 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (351 votes). Check out past polls.