pickRandom.js (5725B)
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.createPickRandom = void 0; 7 8 var _array = require("../../utils/array.js"); 9 10 var _factory = require("../../utils/factory.js"); 11 12 var _is = require("../../utils/is.js"); 13 14 var _seededRNG = require("./util/seededRNG.js"); 15 16 var name = 'pickRandom'; 17 var dependencies = ['typed', 'config', '?on']; 18 var createPickRandom = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) { 19 var typed = _ref.typed, 20 config = _ref.config, 21 on = _ref.on; 22 // seeded pseudo random number generator 23 var rng = (0, _seededRNG.createRng)(config.randomSeed); 24 25 if (on) { 26 on('config', function (curr, prev) { 27 if (curr.randomSeed !== prev.randomSeed) { 28 rng = (0, _seededRNG.createRng)(curr.randomSeed); 29 } 30 }); 31 } 32 /** 33 * Random pick one or more values from a one dimensional array. 34 * Array elements are picked using a random function with uniform or weighted distribution. 35 * 36 * Syntax: 37 * 38 * math.pickRandom(array) 39 * math.pickRandom(array, number) 40 * math.pickRandom(array, weights) 41 * math.pickRandom(array, number, weights) 42 * math.pickRandom(array, weights, number) 43 * math.pickRandom(array, { weights, number, elementWise }) 44 * 45 * Examples: 46 * 47 * math.pickRandom([3, 6, 12, 2]) // returns one of the values in the array 48 * math.pickRandom([3, 6, 12, 2], 2) // returns an array of two of the values in the array 49 * math.pickRandom([3, 6, 12, 2], { number: 2 }) // returns an array of two of the values in the array 50 * math.pickRandom([3, 6, 12, 2], [1, 3, 2, 1]) // returns one of the values in the array with weighted distribution 51 * math.pickRandom([3, 6, 12, 2], 2, [1, 3, 2, 1]) // returns an array of two of the values in the array with weighted distribution 52 * math.pickRandom([3, 6, 12, 2], [1, 3, 2, 1], 2) // returns an array of two of the values in the array with weighted distribution 53 * 54 * math.pickRandom([{x: 1.0, y: 2.0}, {x: 1.1, y: 2.0}], { elementWise: false }) 55 * // returns one of the items in the array 56 * 57 * See also: 58 * 59 * random, randomInt 60 * 61 * @param {Array | Matrix} array A one dimensional array 62 * @param {Int} number An int or float 63 * @param {Array | Matrix} weights An array of ints or floats 64 * @return {number | Array} Returns a single random value from array when number is 1 or undefined. 65 * Returns an array with the configured number of elements when number is > 1. 66 */ 67 68 69 return typed(name, { 70 'Array | Matrix': function ArrayMatrix(possibles) { 71 return _pickRandom(possibles, {}); 72 }, 73 'Array | Matrix, Object': function ArrayMatrixObject(possibles, options) { 74 return _pickRandom(possibles, options); 75 }, 76 'Array | Matrix, number': function ArrayMatrixNumber(possibles, number) { 77 return _pickRandom(possibles, { 78 number: number 79 }); 80 }, 81 'Array | Matrix, Array | Matrix': function ArrayMatrixArrayMatrix(possibles, weights) { 82 return _pickRandom(possibles, { 83 weights: weights 84 }); 85 }, 86 'Array | Matrix, Array | Matrix, number': function ArrayMatrixArrayMatrixNumber(possibles, weights, number) { 87 return _pickRandom(possibles, { 88 number: number, 89 weights: weights 90 }); 91 }, 92 'Array | Matrix, number, Array | Matrix': function ArrayMatrixNumberArrayMatrix(possibles, number, weights) { 93 return _pickRandom(possibles, { 94 number: number, 95 weights: weights 96 }); 97 } 98 }); 99 /** 100 * @param {Array | Matrix} possibles 101 * @param {{ 102 * number?: number, 103 * weights?: Array | Matrix, 104 * elementWise: boolean 105 * }} options 106 * @returns {number | Array} 107 * @private 108 */ 109 110 function _pickRandom(possibles, _ref2) { 111 var number = _ref2.number, 112 weights = _ref2.weights, 113 _ref2$elementWise = _ref2.elementWise, 114 elementWise = _ref2$elementWise === void 0 ? true : _ref2$elementWise; 115 var single = typeof number === 'undefined'; 116 117 if (single) { 118 number = 1; 119 } 120 121 var createMatrix = (0, _is.isMatrix)(possibles) ? possibles.create : (0, _is.isMatrix)(weights) ? weights.create : null; 122 possibles = possibles.valueOf(); // get Array 123 124 if (weights) { 125 weights = weights.valueOf(); // get Array 126 } 127 128 if (elementWise === true) { 129 possibles = (0, _array.flatten)(possibles); 130 weights = (0, _array.flatten)(weights); 131 } 132 133 var totalWeights = 0; 134 135 if (typeof weights !== 'undefined') { 136 if (weights.length !== possibles.length) { 137 throw new Error('Weights must have the same length as possibles'); 138 } 139 140 for (var i = 0, len = weights.length; i < len; i++) { 141 if (!(0, _is.isNumber)(weights[i]) || weights[i] < 0) { 142 throw new Error('Weights must be an array of positive numbers'); 143 } 144 145 totalWeights += weights[i]; 146 } 147 } 148 149 var length = possibles.length; 150 var result = []; 151 var pick; 152 153 while (result.length < number) { 154 if (typeof weights === 'undefined') { 155 pick = possibles[Math.floor(rng() * length)]; 156 } else { 157 var randKey = rng() * totalWeights; 158 159 for (var _i = 0, _len = possibles.length; _i < _len; _i++) { 160 randKey -= weights[_i]; 161 162 if (randKey < 0) { 163 pick = possibles[_i]; 164 break; 165 } 166 } 167 } 168 169 result.push(pick); 170 } 171 172 return single ? result[0] : createMatrix ? createMatrix(result) : result; 173 } 174 }); 175 exports.createPickRandom = createPickRandom;