in reply to Re: Array Shuffle
in thread Array Shuffle

From perlsec:

Also note that while the order of the hash elements might be randomised, this "pseudoordering" should not be used for applications like shuffling a list randomly (use List::Util::shuffle() for that, see List::Util, a standard core module since Perl 5.8.0; or the CPAN module Algorithm::Numerical::Shuffle), or for generating permutations (use e.g. the CPAN modules Algorithm::Permute or Algorithm::FastPermute), or for any cryptographic applications.
And indeed, your subroutine returns the same order if you call it twice for the same array in the same perl instance.

Your code doesn't guarantee that no elements get to their place.

If you don't have the criterion that no elements get into their place, I see no reason to use this stupid way instead of one of the simpler ways:

  1. use List::Util "shuffle"; sub shuffleArray{ shuffle(@_); }
  2. sub shuffleArray{ my @p = @_; my $k; $k = $_ + int(rand(@p - $_)), @p[$_, $k] = @p[$k, $_] for 0 .. @p - 1; @p; }
  3. sub shuffleArray{ my @p = @_; map { splice @p, $_ + rand(@p - $_), 1, $p[$_] } 0 .. @p - 1; }
  4. sub shuffleArray{ my @p = @_; my $t; map { $t = splice @p, rand(@p), 1, $p[0]; shift @p; $t } 0 .. +@p - 1; }
  5. sub shuffleArray{ my @w = map { rand } @_; @_[sort { $w[$a] <=> $w[$b] } 0 .. @_ - 1]; }
  6. sub shuffleArray{ map { $$_[1] } sort { $$a[0] <=> $$b[0] } map { [rand, $_] } @ +_; }
  7. sub shuffleArray{ map { $$_[0] } sort { ref $a <=> ref $b } map { bless [$_], ra +nd } @_; }