Случайное значение из массива по массе в php
Я понимаю, что этот вопрос, скорее всего, был задан, но я не понимаю предыдущих вопросов достаточно, чтобы знать, делают ли они то, что я хочу.
$fruits = array('20' => 'apple', '40' => 'orange', '40' => 'pear');
Ключи представляют собой процентное соотношение шансов на получение стоимости. Я хотел бы mt_rand() число от 0 до 99 и вернуть значение из $fruit на основе этих процентов.
Очень возможно, я так запутался, потому что не знаю, как объяснить, что я ищу.
Заранее спасибо за помощь.
Изменить: требуется случайное значение из $fruit, исходя из этих шансов:
Я хочу 40% шанс получить апельсин, 40% шанс получить грушу и 80% шанс получить яблоко.
Изменить: Чтобы уточнить, так как многие ответы получили неправильное (или я просто не понимаю их код), мне нужен был результат независимо от того, какой номер я выбираю, а не только 20, 40 или 40.
Ответы
Ответ 1
Я думаю, что что-то вроде этого сделает то, что вы хотите:
(нажмите кнопку отправки несколько раз на образце, чтобы получить код для повторного выполнения)
$fruits = array('apple' => '20', 'orange' => '40', 'pear' => '40');
$newFruits = array();
foreach ($fruits as $fruit=>$value)
{
$newFruits = array_merge($newFruits, array_fill(0, $value, $fruit));
}
$myFruit = $newFruits[array_rand($newFruits)];
Это создает массив ($newFruits
), который представляет собой числовой индексный массив со 100 элементами. 20 из этих элементов - "яблоко", 40 - "оранжевое", а 40 - "груша". Затем мы выбираем случайный индекс из этого массива. 20 раз из 100 вы получите "яблоко", 40 раз из 100 вы получите "оранжевый", а 40 раз из 100 вы получите "грушу".
Ответ 2
Прежде всего, ваш массив имеет только два элемента (яблоко и груша), потому что груша перезаписывает оранжевый из-за наличия того же ключа. Поэтому используйте обратный порядок. Кроме того, не ставьте кавычки вокруг целых чисел:
$fruits = array('apple' => 20, 'orange' => 40, 'pear' => 40);
Вы должны выбрать случайное число, затем сравнить каждый вес массива плюс сумму предыдущих весов, пока не получите соответствие:
$rand = rand(1,100);
$sum = 0;
$chosenFruit;
foreach ($fruits as $f=>$v) {
$sum += $v;
if ( $sum >= $rand ) {
$chosenFruit = $f;
break;
}
}
echo "We have chosen the {$chosenFruit}!";
Вы даже можете сделать процедуру более упругой, заменив значение 100
в функции rand() на вычисленную сумму значений массива $fruits.
Ответ 3
$key = rand(1,98); // rand() is inclusive of the range, hence 1-98.
foreach( $fruits as $k => $v){
if( $k == $key) {
echo 'Chosen fruit is:' . $v;
break;
}
}
Ответ 4
Есть несколько дорог, чтобы спуститься с этим, и они в значительной степени зависят от ваших данных. Используя проценты, 0 - 100, у вас может быть 100 элементов в вашем массиве, каждая из которых соответствует проценту, или вы можете иметь распределение с назначенными значениями (подобно массиву в вашем примере).
Предполагая первое, вы можете использовать:
$key = mt_rand(0, 100);
$fruit = isset($fruits[$key]) ? $fruits[$key] : false;
Вышеупомянутое может также работать с дистрибутивом, чтобы проверить, существует ли "плод", но обычно вам нужно "если процент <=
значение, используйте этот фрукт". Что-то вроде этого можно сделать с помощью:
$key = mt_rand(0, 100);
$fruit = false;
foreach ($fruits as $percent => $value) {
if ($percent <= $key) {
$fruit = $value;
break;
}
}
Теперь, забавная часть. Что делать, если вы хотите, чтобы какой-либо из фруктов имел процент выше значения? Вы можете изменить выше, чтобы сохранить каждый плод, который соответствует массиву, а затем выбрать случайное значение из этого массива:
$key = mt_rand(0, 100);
$matches = array();
foreach ($fruits as $percent => $value) {
if ($percent <= $key) {
$matches[] = $value;
}
}
$select = mt_rand(0, count($matches) - 1);
$fruit = $matches[$select];