-1

I want to add exactly 5 random numbers to an array, but each number must be different. Here is what I have so far...

$col_B = array();

for ($i=1; $i < 6; $i++) { 
    $rand = $col_ranges['B'][rand ( 0 , 14 )]; // calls to an array of numbers
    if(!in_array($rand, $col_B)){
        $col_B[] = $rand;   
    }
    else{ $i - 1;}

}
echo implode($col_B, '<br>');
Nicholas P.
  • 353
  • 4
  • 14
  • 1
    And what is the problem? Please also provide the value of `$col_ranges['B']` – trincot Dec 28 '15 at 20:43
  • It doesn't add exactly 5 numbers, if it is not in the array then the loop continues on instead of looking for another random number to add. – Nicholas P. Dec 28 '15 at 20:45

3 Answers3

5

I would not use a for loop here, but rather a while loop that executes until the random number array hits the desired count. Your issue is that $i continues to increment regardless of whether you add $rand to your array.

$col_B = array();

while( count($col_B) < 5 ) 
{
    $rand = $col_ranges['B'][rand ( 0 , 14 )]; // calls to an array of number

    if( ! in_array($rand, $col_B) )
        $col_B[] = $rand;
}
Chris
  • 4,762
  • 3
  • 44
  • 79
  • This just broke the script entirely causing a 503 error and the page just loads and loads. – Nicholas P. Dec 28 '15 at 20:59
  • I'm not sure what `$col_ranges` is made of, so its difficult to debug. My guess is `$rand` is not what you expect. Try printing it out and see what you expect – Chris Dec 28 '15 at 21:03
1

The problem is that you go to the next $i value even if when you just had a duplicate pick, meaning you will not always get to your total of 5 values.

But instead of fixing that, I would suggest to not try and try until you get a non-used value, but to remove values once you have picked them, so they cannot be picked again.

This you can do by first taking a temporary copy of your original array, and removing the elements (using array_splice) as you pick them so that in the next iteration they are no longer available for picking:

$temp = $col_ranges['B'];
for ($i=1; $i < 6; $i++) { 
    $col_B[] = array_splice($temp, rand ( 0 , count($temp)-1 ), 1)[0];
}

Note that the range of values given to rand is decreased every time (count becomes smaller as the array becomes shortened by the array_splice).

This is more efficient as you know for sure the loop will only iterate 5 times and never more.

Alternative

An interesting alternative is using the shuffle and array_slice functions, again using a copy of the original array. This way you don't need the loop at all:

$col_B = $col_ranges['B'];
shuffle($col_B); // randomise the array
$col_B = array_slice($col_B, 0, 5); // keep only first 5
trincot
  • 317,000
  • 35
  • 244
  • 286
0
$col_B = array();

for ($i=1; $i < 6; $i++) { 
  while(true){
    $rand = $col_ranges['B'][rand ( 0 , 14 )]; // calls to an array of number
    if(!in_array($rand, $col_B)){
        $col_B[$i] = $rand; 
      break;
    }
    else{ continue;}
  }

}
echo implode($col_B, '<br>');
Rajesh Jangid
  • 724
  • 6
  • 13
  • Perfect! This did exactly what I wanted. Thank you!! – Nicholas P. Dec 28 '15 at 21:01
  • It will do the job. But it is not so optimal as it might loop a lot of times, while it is quite easy to have a solution where it will find the unique values in exactly 5 iterations. – trincot Dec 28 '15 at 21:22