Both answers above rely on methods that will get slow quickly, especially the accepted one.
function weighted_random(items, weights) {
var i;
for (i = 0; i < weights.length; i++)
weights[i] += weights[i - 1] || 0;
var random = Math.random() * weights[weights.length - 1];
for (i = 0; i < weights.length; i++)
if (weights[i] > random)
break;
return items[i];
}
I replaced my older ES6 solution with this one as of December 2020, as ES6 isn't supported in older browsers, and I personally think this one is more readable.
If you'd rather use objects with the properties item
and weight
:
function weighted_random(options) {
var i;
var weights = [];
for (i = 0; i < options.length; i++)
weights[i] = options[i].weight + (weights[i - 1] || 0);
var random = Math.random() * weights[weights.length - 1];
for (i = 0; i < weights.length; i++)
if (weights[i] > random)
break;
return options[i].item;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…