note 25007 added to function.shuffle
| From: | php-general at lists dot php dot net | Date: | Sat, 07 Sep 2002 17:02:57 +0000 |
| Subject: | note 25007 added to function.shuffle | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-36306@lists.php.net to get a copy of this message | ||
The one-liner code does not work well and is still incorrect after the proposed patch, as the first
loop is executed without initializing $r:
for($c = count($arr); $c > 0; $r = mt_rand(0, $c--))
array_splice($arr, $r, $c - $r, array_reverse(array_slice($arr, $r, $c - $r)));
The correct way would be to use:
for($c = count($arr); $c > 0; $c--) {
$r = mt_rand(0, $c);
array_splice($arr, $r, $c - $r, array_reverse(array_slice($arr, $r, $c - $r)));
}
Still, it runs too slowly, because of the many array copies and creation by the internal
array_splice and array_reverse.
Use it only with small arrays, as the time needed grows in O(N^2) where N is the count of element in
the array...
A faster approach, in O(N), does not reverse a splice, but swaps each position with a random
position in the array. The following code works with indexed array (with integer keys from 0 to
N-1), not with associative arrays:
for($c = count($arr); $c > 0; $c--) {
$r = mt_rand(0, $c);
$v = $arr[$c];
$arr[$c] = $arr[$r];
$arr[$r] = $v;
}
To use this technic with large associative arrays, one can first shuffle a range(0, count($arr)),
then use array_multisort() to sort the $arr by this shuffled range.
--
http://www.php.net/manual/en/function.shuffle.php
http://master.php.net/manage/user-notes.php?action=edit+25007
http://master.php.net/manage/user-notes.php?action=delete+25007
http://master.php.net/manage/user-notes.php?action=reject+25007