How to generate a random weighted distribution of elements

前端 未结 4 344
执笔经年
执笔经年 2021-01-13 07:04

I would like to return an array which has a set of unique elements randomly distributed according to custom frequency. My real world use-case is the repetition of carousel i

4条回答
  •  隐瞒了意图╮
    2021-01-13 07:33

    Let's say you take your distribution numbers as an array of objects, like this:

    var items = [
        {item: "A", weight: 20}, 
        {item: "B", weight: 50}, 
        {item: "C", weight: 80},
        {item: "D", weight: 10}
    ];
    

    This removes any assumption that your weights add up to 100% - they might be click-counts, or votes, or any other value you like. Then you can do this:

    function weightedSelect(items) {
        // Get the total, and make the weights cummulative
        var total = items.reduce(function(sum, item){
            item.weight = item.weight + sum;
            return item.weight;
        },0);
    
        var r = Math.random() * total;
    
        // Can't use .forEach() here because we want early termination
        for (var i = 0; i < items.length; i++) {
             if (r < items[i].weight)
                 return items[i].item;
        }
    }
    

    I'm not sure how this compares to the other implementations for efficiency, but it's concise.

提交回复
热议问题