Andy
Andy

Reputation: 5395

PHP array_rand in loop where value is always different from previous value

I have a PHP script as follows:

<?php
$a = [1 => 1, 2 => 2, 3 => 3];

for ($x=1; $x<10; $x++) {
    $r = array_rand($a);
    echo $a[$r] . '<br>';
}
?>

The output for this is random every time, but as an example it may be this:

2 1 3 3 2 3 1 3 2

What I'm trying to achieve is to make sure that each time a value is output it is different from the previous value. So in the example above I don't want 3 3 to occur.

I tried to come up with my own solution which involved storing the "current" output value in a variable called $current_value and making sure it's not what's going to be output next:

<?php
$a = [1 => 1, 2 => 2, 3 => 3];

$current_value = false;
for ($x=1; $x<10; $x++) {

    if ($current_value) {
        $r = array_rand($a);
        while ($current_value !== $r) {
            echo $a[$r] . '<br>';
            $current_value = $a[$r];
        }
    } else {
        $r = array_rand($a);
        echo $a[$r] . '<br>';
        $current_value = $a[$r];
    }
}
?>

Although I don't get the same value appearing in sequence (at least from what I've tested) the loop only outputs a random number of figures which is usually less than $x<10. My guess here is that there's nothing to handle $current_value == $r so it simply outputs nothing?

Please could someone advise on how to achieve this? The expected output is 9 (or whatever the for loop counter is set to) integers with no overlap in the sequence, e.g.

2 1 3 1 2 3 1 3 2

Edit: The value which is output must always be 1, 2 or 3. This is why I was using $a as defined.

Upvotes: 0

Views: 882

Answers (6)

Viktor
Viktor

Reputation: 722

I believe this code would do what you want:

<?php
$a = [1, 2, 3];

$current_value = false;
for ($x=1; $x<10; $x++) {
    $r = array_rand($a, 1);
    if ($current_value !== $r) {
        echo $a[$r] . '<br>';
        $current_value = $r;
    }else{
        $x--;
    }
}

Upvotes: 2

Gabriel Heming
Gabriel Heming

Reputation: 1165

Just make a recursive function.

A function to sort another number if is equal to the last one:

function myRand(array $array , $lastValue = null)
{
    $sorted = $array[array_rand($array)];   
    return $sorted == $lastValue ? myRand($array , $sorted) : $sorted;
}

And the function to do the length/ocurrences of new random array:

function myArrayRand(array $array , $length)
{
    $sortedArray = [];
    while(count($sortedArray) < $length)
    {
        $sortedArray[] = myRand($array , end($sortedArray));
    }

    return $sortedArray;    
}

Execute:

var_dump(myArrayRand([1 , 2 , 3] , 10));

Result:

array(10) {
   [0]=>
      int(1)
      [1]=>
      int(3)
      [2]=>
      int(2)
      [3]=>
      int(3)
      [4]=>
      int(1)
      [5]=>
      int(3)
      [6]=>
      int(1)
      [7]=>
      int(2)
      [8]=>
      int(1)
      [9]=>
      int(2)
}

As array_rand return the randomized key from the array, I've put the sorted return as key from $array. That's why you don't need use an indexed array.

Upvotes: 2

Azeez Kallayi
Azeez Kallayi

Reputation: 2642

You can try with end() function . Below code may help you

$a = array(1,2,3);
$out = array();
for ($x=1; $x<=10; $x++) {

$r = array_rand($a);
if(!end($out)== $r)
{
     $out[] = $r;
     echo $a[$r] . '<br>';
}
else
{
    $x=$x-1;
}

}

Upvotes: 0

Christian Felix
Christian Felix

Reputation: 673

Not sure if I have fully understand, but maybe you after something like this:

$a = [1 => 1, 2 => 2, 3 => 3];
$prev_value = false;
$results = [];
for ($x=1; $x<10; $x++) {
    $rand = array_rand($a);
    if($prev_value == $rand){
      do{
        $rand = array_rand($a);
      }while($prev_value === $rand);
}
$results[] = $rand;
$prev_value = $rand;
}

Upvotes: 0

Tariq
Tariq

Reputation: 218

try like this

$a = [1 => 1, 2 => 2, 3 => 3];
$pre_index=-1;
for ($x=1; $x<10; $x++) {

   $r = array_rand($a);
   if($pre_index==-1){

        echo $a[$r] . '<br>';
         $pre_index=$r;
   }else {

       while($pre_index==$r){

          $r = array_rand($a);

              }


    echo $a[$r] . '<br>';
    $pre_index=$r;
   }
}

Upvotes: 0

Hikmat Sijapati
Hikmat Sijapati

Reputation: 6994

Like this.use goto.The goto operator can be used to jump to another section in the program.

<?php
$a = [1 => 1, 2 => 2, 3 => 3];

$current_value = false;
for ($x=1; $x<10; $x++) {

    if ($current_value) {
        loop: $r = array_rand($a);
        if($current_value !== $r){
             echo $a[$r] . '<br>';
             $current_value = $a[$r];
        }
        else{
           goto loop; 
        }

    } else {
        $r = array_rand($a);
        echo $a[$r] . '<br>';
        $current_value = $a[$r];
    }
}
?>

For more see docs http://php.net/manual/en/control-structures.goto.php

Upvotes: 0

Related Questions