I want to select a random value from a array, but keep it unique as long as possible.
For example if I'm selecting a value 4 times from a array of 4 elements, the selected value should be random, but different every time.
If I'm selecting it 10 times from the same array of 4 elements, then obviously some values will be duplicated.
I have this right now, but I still get duplicate values, even if the loop is running 4 times:
$arr = $arr_history = ('abc', 'def', 'xyz', 'qqq');
for($i = 1; $i < 5; $i++){
if(empty($arr_history)) $arr_history = $arr;
$selected = $arr_history[array_rand($arr_history, 1)];
unset($arr_history[$selected]);
// do something with $selected here...
}
You almost have it right. The problem was the
unset($arr_history[$selected]);
line. The value of$selected
isn't a key but in fact a value so the unset wouldn't work.To keep it the same as what you have up there:
Or an example with a few less lines:
If you do not care about what particular values are in the array, you could try to implement a Linear Congruential Generator to generate all the values in the array.
LCG implementation
Wikipedia lists some values you can use, and the rules to select the values for the LCG algorithm, because the LCG algorith is deterministic it is guaranteed not to repeat a single value before the length of the period.
After filling the array with this unique numbers, you can simply get the numbers in the array 1 by 1 in order.
How about shuffling the array, and popping items off.
When
pop
returnsnull
, reset the array.Of course, you'll want to encapsulate this better, and do better checking, and other such things.
http://codepad.org/sBMEsXJ1
Easy and clean:
I've done this to create a random 8 digit password for users: