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

Hi,

I've got an array with about 170000 records. I tried doing @source = sort { rand(1) >= .5 } @source; but it doesn't randomize anything.

Any ideas or other ways of doing this?

Thanks,
Ralph.

Replies are listed 'Best First'.
Re: Randomizing an array
by diotalevi (Canon) on Jun 14, 2003 at 14:31 UTC

    Run the following command

    perldoc -q shuffle
Re: Randomizing an array
by cciulla (Friar) on Jun 14, 2003 at 14:32 UTC

    A quick glance at the FAQs provides:

    use List::Util 'shuffle'; @shuffled = shuffle(@list);
    ...and...
    sub fisher_yates_shuffle { my $deck = shift; # $deck is a reference to an array 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 in place print @mpeg;

Re: Randomizing an array
by Dr. Mu (Hermit) on Jun 14, 2003 at 16:39 UTC
    The above comments are spot on, but it may still be instructive to see why your rand method gave such poor results. The reason is that sort wants a comparison result that's -1 (less than), 0 (equal), or 1 (greater than). In your program, only 0 and 1 can result from the comparison. If you substitute the three-way comparison operator <=> for the >=, you'll see a big improvement in the rearranging. (Granted, rand(1) <=> 0.5 won't yield 0 very often, but that doesn't matter. What's important is that -1 and 1 occur with roughly equal preponderance.)

    Update: Looks like belg4mit beat me to it!

Re: Randomizing an array
by belg4mit (Prior) on Jun 14, 2003 at 16:37 UTC
    FYI perldoc sort explains why your solution fails. Sort expects a (consistent) tri-state value be returned by the sorting routine eg; -1, 0, 1. Both cmp and <=> do, wheras your block does not.

    --
    I'm not belgian but I play one on TV.

Re: Randomizing an array
by The Mad Hatter (Priest) on Jun 14, 2003 at 14:36 UTC
    See perldoc -q shuffle.

    Update Seems diotalevi beat me to it. ; )

Re: Randomizing an array
by vek (Prior) on Jun 14, 2003 at 23:29 UTC
Re: Randomizing an array
by svsingh (Priest) on Jun 15, 2003 at 08:14 UTC
    This is similar to a shuffle routine I wrote in college. Basically, you swap two elements in the array at random. I used to do this n^2 times, but since you have so many elements, that may not be too effective for you. Instead I took a cue from cciulla's post and perform n swaps. For 170,000 elements, it didn't take too long to run on my end.
    my @shuffledList = &shuffle(1..170000); sub shuffle { my @sl = @_; # soon to be Sorted List for my $i ( 1..$#sl ) { my $x = int(rand() * $#sl); my $y = int(rand() * $#sl); ($sl[$x], $sl[$y]) = ($sl[$y], $sl[$x]); } return @sl; }
    Hope this helps.