JSFiddle - React, Tailwind, and code Playground

HTML

<button onclick="run()">run</button>

JavaScript

(function(global){

// algorithm - 重みをつけて乱択する http://blog.livedoor.jp/dankogai/archives/51761113.html
// バイナリサーチ版
var make_random_picker = function(picks){
    var i, l = picks.length, t = 0, choices = picks.concat();
    for (i = 0; i < l; ++i) { choices[i][1] = (t += choices[i][1]); }
    for (i = 0; i < l; ++i) { choices[i][1] /= t; }
    return function() {
        var r = Math.random(), head = 0, tail = l - 1;
        while (head <= tail) {
            var sum = head + tail;
            var mid = (sum <= 0x7fffffff) ? (sum >> 1) : Math.floor(sum / 2); 
            if (r < choices[mid][1]) {
                if (mid == 0 || r >= choices[mid-1][1]) {
                    return choices[mid][0];
                }
                tail = mid - 1;
            }
            else {
                head = mid + 1;
            }
        }
        return null; // never.
    };
};

// 実行
global.run = function() {

    var data = [];
    var result = {'null' : 0};

    for (var i = 0; i < 100; i++) {
    var key = 'nnn' + i;
        data.push([key, 1]);
        result[key] = 0;
    }

    var s = new Date();

    var pick = make_random_picker(data);

    alert('make time:' + (new Date() - s) + '(ms)');
    var s = new Date();

    var n = 100000;
    for(var i = 0; i < n; i++) {
    var v = pick();
        result[v]++;
    }

    if (!confirm('run time:' + (new Date() - s) + '(ms). cancel print log?')) {
    var buf = [];
    buf.push('null:' + result['null'] + '(' + ((result['null']/n)*100).toFixed(3) + '%)');
    for (var i = 0; i < data.length; i++) {
        buf.push(data[i][0] + ':' + result[data[i][0]]+'(' + ((result[data[i][0]]/n)*100).toFixed(3) + '%)');
    }
    log(buf.join('\n'));
    function log(s) {
        if (window.console) console.log(s);
        else if (window.opera) opera.postError(s);
    }
}
    
};

})(this)