4

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

5
  • 2
    note their position, remove them, shuffle, put them back in Commented Nov 3, 2014 at 16:46
  • Should those two values be randomized in the entire array, or just in terms of their own positions? Commented Nov 3, 2014 at 16:47
  • 1
    So do you want to swap hamster and gerbil 50% of the time, or do you want to randomize their position in the array? Commented Nov 3, 2014 at 16:47
  • I want to randomise their positions instead of a straight 50/50 split, and i want to randomise them in terms of their own position rather than in the entire array Commented Nov 3, 2014 at 16:49
  • @odd_duck: So in this case, you'd like to shuffle the 7th and 8th indices of the array? Commented Nov 3, 2014 at 16:51

4 Answers 4

10

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);
Sign up to request clarification or add additional context in comments.

7 Comments

@BenM this is an answer giving the idea on how solve the question. It's still a valid answer even though it didn't involved the actual code part since the asker has the proper knowledge on how to implement the solution.
@BenM I have to agree with Alex... This IS an answer for the user's issue ;)
I completely agree with Alex here, just because it doesn't give out a copy/paste solution, doesn't make it any less of an answer. I actually prefer that, as it still requires for the user to do some work.
OK, I don't understand where my original comment went, but when I commented, there was literally nothing more here than the opening sentence. Anyway, this now is a valid answer :)
+1, any idea on the efficiency of this over other approaches? eg shuffle only (needed) indexes and then just permute/re-arrange the original array?
|
1

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:

  1. Efficiently pick n random elements from PHP array (without shuffle)

Comments

0
$animals = array (
'giraffe',
'lion',
'hippo',
'dog',
'cat',
'rabbit',
'fly',
'goldfish'
);
$other = array('hamster','gerbil');
$allAnimals = array();
foreach($animals as $key => $animal){
    if($key == 7){
        $allAnimals = array_merge($allAnimals,shuffle($other));
    }
$allAnimals[] = $animal;
}

1 Comment

What if the index is not always the 7th?
0
function shuffle_include($a, $include_indexes)    
{    
    $b = array();    
    foreach ($include_indexes as $i => $v)    
        $b[] = $a[$v];    
            
    shuffle($b);    
    
    foreach ($include_indexes as $i => $v)    
        $a[$v] = $b[$i];    
     
    return $a;    
}

Example:

$animals = array (
'giraffe',
'lion',
'hippo',
'dog',
'cat',
'rabbit',
'fly',
'hamster',
'gerbil',
'goldfish');

$new_animals = shuffle_include($animals, array(7,8));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.