0

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.

0

6 Answers 6

2

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

2 Comments

The number which is output must be 1, 2 or 3. That's why I was using an indexed array. The code above does seem to work but is giving me value 0, 1 or 2.
instead of printing the index I've had it print the value now. Should run better
2

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.

2 Comments

That's giving me Parse error: parse error, expecting { on the line which begins function myArrayRand(array $array , int $length) : array. I've copied/pasted it exactly into my script.
@Andy That's because I wrote in PHP 7 and you're using an old version of PHP. I'll downgrade to PHP < 7.
0

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

Comments

0

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;
   }
}

Comments

0

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;
}

Comments

0

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;
}

}

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.