Picks a key with probability proportional to its integer weight. Sums the weights, draws an int in 1..total, then walks the cumulative weight until it meets or exceeds the draw and returns that key. Runs in one pass with no allocation beyond the inputs.

PHP Code Editor

<?php
function weightedRandom(array $weights): string|int {
$total = array_sum($weights);
if ($total <= 0) {
throw new InvalidArgumentException('weights must sum to a positive number');
}
$draw = random_int(1, (int) $total);
$cumulative = 0;
foreach ($weights as $key => $weight) {
$cumulative += $weight;
if ($draw <= $cumulative) {
return $key;
}
}
return array_key_last($weights);
}
$weights = ['common' => 70, 'uncommon' => 25, 'rare' => 5];
$counts = ['common' => 0, 'uncommon' => 0, 'rare' => 0];
for ($i = 0; $i < 10000; $i++) {
$counts[weightedRandom($weights)]++;
}
print_r($counts); // roughly 7000 / 2500 / 500
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PHP Version

Execution Result

Ready to execute

Click the "Run Script" button to see the output here