Слово предупреждения об этом решении.Я бы не использовал его для большого набора чисел.Если бы я делал это то же самое решение для гораздо большего набора, я бы использовал array_splice для удаления выбранных членов из массива.Поскольку вы получаете гораздо больше места, поиск неиспользуемого числа в вашем диапазоне становится довольно дорогим и требует лучшего решения, чем приведенный ниже метод грубой силы.
Это создаст половину вашего целевого набора.Вы будете называть это дважды, один раз для каждой половины.
function build_half($min, $max, $num_elements, $arr = array() ){
while( count($arr) <= $num_elements)
{
$candidate = rand($min, $max);
if( !in_array($candidate, $arr))
{
array_push($arr, $candidate);
}
}
return $arr;
}
Это будет извлекать элементы $ this_many из массива.
function random_grab($arr, $this_many){ // don't try this on the subway
$nums_to_repeat = array();
// catch some edge cases...
if( $this_many > count($arr) )
{
return FALSE;
}
else if( $this_many == count($arr) )
{
return shuffle($arr);
}
while( count($nums_to_repeat) <= $this_many)
{
$rand_key = rand(0, count($arr) - 1);
if( ! in_array($arr[$rand_key], $nums_to_repeat))
{
array_push($nums_to_repeat, $arr[$rand_key]);
}
}
return $nums_to_repeat;
}
Это довольно специализированный случай, но его можно сделать более общим, допустив, чтобы смещенный пол и потолок передавались в качестве параметров.Для вашей задачи их будет 5 и 9, поэтому мы просто получим их напрямую.
function random_insert_2nd_half($target, $source){
$offsets_consumed = array();
$num_elements = count($target);
while( count($source) > 0 )
{
$offset = rand( ($num_elements/2), $num_elements - 1);
if( ! in_array( $offset, $offsets_consumed)
{
$arr[$offset] = array_pop($nums_to_repeat);
}
}
}
Хорошо, так что после того, как все это сделано, давайте приступим к работе.
// Generate the first half of the array
$my_array = $repeated_nums = array();
$my_array = build_half(1, 10, 5);
// then grab the 2 random numbers from that first half.
$repeated_nums = random_grab($my_array, 2);
// So now we have our random numbers and can build the 2nd half of the array.
// we'll just repeat the call to the first function.
$my_array = build_half(1, 10, 5, $my_array);
// Then swap out two of the values in the second half.
$my_array = random_insert_2nd_half($my_array, $repeated_nums);
// at this point $my_array should match what you are looking for.