1

I've seen How to run a randomly selected function in JavaScript? which allows for running a JavaScript function randomly selected from at array with an equal chance each time (e.g. if there are two functions in total, there is a 50% chance that each function will be executed each time).

How to write a function to state the percentage chance of executing each function that is randomly available to be chosen from an array of functions? How do I do a weighted randomization??

function randomFrom(array) {
    return array[Math.floor(Math.random() * array.length)];
}
var contentWrapper = function (target,type,articleId) {
  // list type ads
  if (type == 'list') {
    function randomListData() {
      var func = randomFrom([
        function () {
          fnNameA10(target, 'list');
        },
        function () {
          fnNameB20(target, 'list', articleId);
        }
      ]);
      (func)();
    }
    randomListData();
    // content type ads
  } else if (type == 'content') {
    function randomContentData() {
      var func = randomFrom([
        function () {
          fnNameA10(target, 'content');
        },
        function () {
          fnNameB20(target, 'content', articleId);
        }
      ]);
      (func)();
    }
    randomContentAd();
  }
};
8
  • 1
    Do you mean that the function should take in {function:percentage} as input? Commented Dec 3, 2013 at 19:30
  • 1
    ...by asking your instructor to see the answer key? Commented Dec 3, 2013 at 19:30
  • 4
    Are you trying to do weighted randomization? Commented Dec 3, 2013 at 19:32
  • Are you asking how to determine the chance that a function will be called given a equal weighting OR are you asking how to weight a functions chance of being called? Commented Dec 3, 2013 at 19:35
  • 1
    @Steve see this for examples: codetheory.in/… Commented Dec 3, 2013 at 19:47

2 Answers 2

4

Here is your answer:

var rand = function(min, max) {
    return Math.random() * (max - min) + min;
};

var getRandomItem = function(list, weight) {
    var total_weight = weight.reduce(function (prev, cur, i, arr) {
        return prev + cur;
    });

    var random_num = rand(0, total_weight);
    var weight_sum = 0;
    //console.log(random_num)

    for (var i = 0; i < list.length; i++) {
        weight_sum += weight[i];
        weight_sum = +weight_sum.toFixed(2);

        if (random_num <= weight_sum) {
            return list[i];
        }
    }

    // end of function
};

var list = ['javascript', 'php', 'ruby', 'python'];
var weight = [0.5, 0.2, 0.2, 0.1];
var random_item = getRandomItem(list, weight);
Sign up to request clarification or add additional context in comments.

4 Comments

I liked your original setup sPaz.
@Emmentaler I didn't know your answer was accepted already. :P Here, take my upvote...
@sPaz, in fairness you provided a working solution (in the comments) few seconds before Emmentaler and I promised to accept your answer if you submitted one. Thanks again. :)
I think that is fair. I borrowed his start anyway :-)
3

http://plnkr.co/edit/wzKp8PqNJ4Fmyo2504Cu?p=preview

var funcs = [
  {probability: 20, fn: function(){console.log("20%")}},
  {probability: 10, fn: function(){console.log("10%")}},
  {probability: 70, fn: function(){console.log("70%")}}
];

var total = 0;
var n = Math.random();
for(var i=0; i<funcs.length; ++i) {
  total+=funcs[i].probability;
  if(n*100<total) {
    funcs[i].fn.call(this);
    break;
  }
}

Here I am getting a random number between 0 and 1 then determining where that number falls in array. I do this by stacking the percentages up and comparing the number to the total amount. I need the break because every element in the array will come back true once the condition is met and I only want the first one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.