2017-04-23 98 views
0

例如:数组中有四个项目。我想获得一个随机,就像这样:如何在Javascript中选择加权随机数组元素?

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 
] 
+4

可能的复制[生成加权随机数] (http://stackoverflow.com/questions/8435183/generate-a-weighted-random-number) –

回答

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. 
+0

这适用于小整数(这也是我的用例),但因为它的工作原理是创建一个新的数组长度等于权重总和,它可能会变得很大/很慢。它也不适用于非整数,因此您需要找到达到整数的最小公分母(对于非常精确的权重,这可能是不可能的)。 – mattsoave

0

一些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; 
相关问题