2017-04-23 93 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; 
相關問題