I have an array as so:
$animals = array (
'giraffe',
'lion',
'hippo',
'dog',
'cat',
'rabbit',
'fly',
'hamster',
'gerbil'
'goldfish'
);
That is the order i want the array to be in apart from these 2 - hamster
and gerbil
I would like to randomise between which one comes first. I know i can use:
shuffle($animals);
To randomise them all but i want to do it for just these 2. So if i was to do a print_r($animals)
i may get hamster come before gerbil but another time get gerbil before hamster
You can splice
the array for those to elements, randomize their order and put them back in the original array:
$sub = array_splice($animals, 7, 2); shuffle($sub); array_splice($animals, 7, 0, $sub); var_dump($animals);
Adding 2 variations of Fisher-Yates-Knuth unbiased shuffling algorithm, with only included indices or excluded indices (php-like pseudo-code)
function shuffle_include( $a, $inc )
{
// $a is array to shuffle
// $inc is array of indices to be included only in the shuffle
// all other elements/indices will remain unaltered
// fisher-yates-knuth shuffle variation O(n)
$N = count($inc);
while ( $N-- )
{
$perm = rnd( 0, $N );
$swap = $a[ $inc[$N] ];
$a[ $inc[$N] ] = a[ $inc[$perm] ];
$a[ $inc[$perm] ] = $swap;
}
// in-place
return $a;
}
function shuffle_exclude( $a, $exc )
{
// $a is array to shuffle
// $exc is array of indices to be excluded from the shuffle
// all other elements/indices will be shuffled
// assumed excluded indices are given in ascending order
$inc = array();
$i=0; $j=0; $l = count($a); $le = count($exc)
while ($i < $l)
{
if ($j >= $le || $i<$exc[$j]) $inc[] = $i;
else $j++;
$i++;
}
// rest is same as shuffle_include function above
// fisher-yates-knuth shuffle variation O(n)
$N = count($inc);
while ( $N-- )
{
$perm = rnd( 0, $N );
$swap = $a[ $inc[$N] ];
$a[ $inc[$N] ] = $a[ $inc[$perm] ];
$a[ $inc[$perm] ] = $swap;
}
// in-place
return $a;
}
Example:
$a = array(1,2,3,4,5,6);
print_r( shuffle_include( $a, array(0,1,2) ) );
// sample output: [2,1,3,4,5,6] , only 0,1,2 indices are shuffled
print_r( shuffle_exclude( $a, array(0,1,2) ) );
// sample output: [1,2,3,6,5,4], all other indices are shuffled except 0,1,2
NOTE That PHP's shuffle function itself uses a variation of Fisher-Yates-Knuth shuffling algorithm
NOTE2 All shuffle algorithms given (and PHP's original shuffle function) have a (average) time complexity of $O(n)$ (n=size of array to shuffle)
for other variations of shuffle
see:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With