如何在Javascript中选择加权随机数组元素?

问题描述 投票:1回答:3

例如:数组中有四个项目。我想随机得到一个,像这样:

array items = [
    "bike"    //40% chance to select
    "car"     //30% chance to select
    "boat"    //15% chance to select
    "train"   //10% chance to select
    "plane"   //5%  chance to select
]
javascript select random
3个回答
1
投票

你当然可以。这是一个简单的代码:

    // Object or Array. Which every you prefer.
var item = {
    bike:40, // Weighted Probability
    care:30, // Weighted Probability
    boat:15, // Weighted Probability
    train:10, // Weighted Probability
    plane:5 // Weighted Probability
    // The number is not really percentage. You could put whatever number you want.
    // Any number less than 1 will never occur
};

function get(input) {
    var array = []; // Just Checking...
    for(var item in input) {
        if ( input.hasOwnProperty(item) ) { // Safety
            for( var i=0; i<input[item]; i++ ) {
                array.push(item);
            }
        }
    }
    // Probability Fun
    return array[Math.floor(Math.random() * array.length)];
}

console.log(get(item)); // See Console.

3
投票

一些es6方法,使用通配符处理:

const randomizer = (values) => {
let i, pickedValue,
        randomNr = Math.random(),
        threshold = 0;

for (i = 0; i < values.length; i++) {
    if (values[i].probability === '*') {
        continue;
    }

    threshold += values[i].probability;
    if (threshold > randomNr) {
            pickedValue = values[i].value;
            break;
    }

    if (!pickedValue) {
        //nothing found based on probability value, so pick element marked with wildcard
        pickedValue = values.filter((value) => value.probability === '*');
    }
}

return pickedValue;

}

用法示例:

let testValues = [{
    value : 'aaa',
    probability: 0.1
},
{
    value : 'bbb',
    probability: 0.3
},
{
    value : 'ccc',
    probability: '*'
}]

randomizer(testValues); // will return "aaa" in 10% calls, 
//"bbb" in 30% calls, and "ccc" in 60% calls;

1
投票

上述两个答案都依赖于快速变慢的方法,尤其是接受的方法。这个阵列魔术会起作用:

var items = [
    "bike",    //40% chance to select
    "car",     //30% chance to select
    "boat",    //15% chance to select
    "train",   //10% chance to select
    "plane",   //5%  chance to select
];
var chances = [40, 30, 15, 10, 5]; //Chances of being selected

var sum = chances.reduce((acc, el) => acc + el, 0);
var acc = 0;
chances = chances.map(el => (acc = el + acc));
var rand = Math.random() * sum;
var result = items[chances.filter(el => el <= rand).length];

如果你把它变成了一个函数:

function chooseWeighted(items, chances) {
    var sum = chances.reduce((acc, el) => acc + el, 0);
    var acc = 0;
    chances = chances.map(el => (acc = el + acc));
    var rand = Math.random() * sum;
    return items[chances.filter(el => el <= rand).length];
}

这种方法快速,易读。它还具有易于更改输入的优点:您可以轻松地将其更改为接受某种对象。

© www.soinside.com 2019 - 2024. All rights reserved.