UNPKG

random-picker

Version:

Randomly pick an item from a set (using the specified probabilities).

103 lines (88 loc) 1.97 kB
/* * random-picker * https://github.com/skratchdot/random-picker * * Copyright (c) 2014 skratchdot * Licensed under the MIT license. */ 'use strict'; var randomGenerator = require('random-seed'); var cleanScore = function (score) { var num = score === undefined ? 1 : parseFloat(score); num = isNaN(num) ? 1 : num; if (!Number.isFinite(num) || num < 0) { num = 0; } return num; }; var Option = function (value, score) { this.value = value; this.score = cleanScore(score); }; var Picker = function (seed) { var api = this; var rand = randomGenerator.create(seed); var total = 0; var options = []; var recalculateTotal = function () { total = 0; for (var i = 0; i < options.length; i++) { total += options[i].score; } }; api.pick = function () { var runningTotal = 0; var randomValue = rand.floatBetween(0, total); for (var i = 0; i < options.length; i++) { runningTotal += options[i].score; if (randomValue < runningTotal) { return options[i].value; } } return null; }; api.option = function (value, score) { var option = new Option(value, score); var added = false; if (option.score <= 0) { api.remove(value); } else { for (var i = 0; i < options.length; i++) { if (options[i].value === option.value) { options[i] = option; added = true; } } if (!added) { options.push(option); } recalculateTotal(); } }; api.removeAll = function () { total = 0; options = []; }; api.remove = function (value) { for (var i = options.length - 1; i >= 0; i--) { if (options[i].value === value) { options.splice(i, 1); } } recalculateTotal(); }; api.size = function () { return options.length; }; api.totalScore = function () { return total; }; api.avgScore = function () { var avg = total / options.length; return Number.isFinite(avg) ? avg : 0; }; return api; }; exports.Picker = function (seed) { return new Picker(seed); };