Search code examples
language-agnostic

Choosing a function to run based on percentages


I'd like to know how to choose a function to run based on a percentage. For example, function1() might have a 60% chance of running, function2() might have a 30% chance of running and function3() might have a 10% chance of running.

I'm writing this in Javascript, but it's not essential that any code given is in Javascript.

I will be wanting to use more than 3 functions and also have the ability to easily modify the percentages. I just whittled it down to 3 for the sake of simplicity.

I've thought about putting all of the functions in an object:

var funcs = {
  '1-10':  func3(){},
  '11-40': func2(){},
  '41-100: func1(){}
}

Then I would generate a random number between 1 and 100, cycle through the object keys and run the function based on the range the randomly generated number appears within. This just doesn't seem right to me an involves too much messing around in order to tweak the percentages. Plus, I feel like I'm reinventing the wheel.

Please could someone suggest a more manageable and elegant way to achieve this?


Solution

  • First thought is using a weighted random of some sort. Googling took me to this npm module and also to this past stackoverflow answer: Generate A Weighted Random Number

    Building on that answer:

    function weightedRand2(spec) {
      var i, sum=0, r=Math.random();
      Object.keys(spec).some(it => {
        sum += parseFloat(it)
        if (r <= sum) {
          spec[it]()
          return true
        }
      })
    }
    
    weightedRand2({0.1: function() {console.log(10)}, 0.3:function() {console.log(30)}, 0.6:function() {console.log(60)}});
    

    This uses decimals with a total summing to 1, rather than percentages.