@antv/data-wizard
Version:
A js/ts library for data processing
205 lines (204 loc) • 7.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BasicRandom = void 0;
var tslib_1 = require("tslib");
var mersenne_twister_1 = tslib_1.__importDefault(require("mersenne-twister"));
var randexp_1 = tslib_1.__importDefault(require("randexp"));
var utils_1 = require("../utils");
var utils_2 = require("./utils");
function isFunction(target) {
return typeof target === 'function';
}
/**
* Basic(bool int float regexp) Generater
* basic generator for bool int float regexp
* @public
*/
var BasicRandom = /** @class */ (function () {
function BasicRandom(seed) {
// if user has provided a function, use that as the generator
if (isFunction(seed)) {
this.random = seed;
}
else {
// If no generator function was provided, use MT
// If seed is undefined, create a random number as seed to avoid the case that timestamps are the same.
this.seed = seed || new Date().getTime() + +("" + Math.random()).slice(2);
this.mt = new mersenne_twister_1.default(this.seed);
this.random = this.mt.random.bind(this.mt);
}
}
/**
* extends class's prototype
* @param options - methods
*
* @example
* ```javascript
* BasiceRandom.mixin({
* percent() {
* return `${this.float({ min: 0, max: 100, fixed: 2 })}%`;
* },
* });
*
* const R = new Random();
* R.percent(); // '10.12%'
* R.n(R.percent, 2) // ['12.10%', '25.22%']
* ```
*/
BasicRandom.mixin = function (options) {
for (var i = 0; i < Object.keys(options || {}).length; i += 1) {
var key = Object.keys(options)[i];
var value = options[key];
this.prototype[key] = value;
}
};
/**
* Return a random boolean value (true or false).
* @param options - options
*/
BasicRandom.prototype.boolean = function (options) {
var likelihood = utils_2.initOptions({ likelihood: 50 }, options).likelihood;
utils_1.assert(likelihood >= 0 && likelihood <= 100, 'Likelihood accepts values from 0 to 100.');
return this.random() > likelihood / 100;
};
/**
* Reture a random integer
* @param options - options
*/
BasicRandom.prototype.integer = function (options) {
var _a = utils_2.initOptions({ min: utils_2.MIN_INT, max: utils_2.MAX_INT }, options), max = _a.max, min = _a.min;
utils_1.assert(min <= max, 'Min cannot be greater than Max.');
return Math.floor(this.random() * (max - min + 1) + min);
};
/**
* Genarate a float / double number
*
* @param options -
*/
BasicRandom.prototype.float = function (options) {
if (options === void 0) { options = {}; }
var opts = utils_2.initOptions({ fixed: 4 }, options);
var base = Math.pow(10, opts.fixed);
var max = utils_2.MAX_INT / base;
var min = -max;
utils_1.assert(!opts.min || !opts.fixed || opts.min >= min, "Min specified is out of range with fixed. Min should be, at least, " + min);
utils_1.assert(!opts.max || !opts.fixed || opts.max <= max, "Max specified is out of range with fixed. Max should be, at most, " + max);
var optss = utils_2.initOptions({ min: min, max: max }, opts);
var num = this.integer({ min: optss.min * base, max: optss.max * base });
var numFixed = (num / base).toFixed(opts.fixed);
return Number.parseFloat(numFixed);
};
/**
* generate an integer number
* @param options -
*/
BasicRandom.prototype.natural = function (options) {
if (options === void 0) { options = {}; }
var opts = utils_2.initOptions({ min: 0, max: utils_2.MAX_INT }, options);
utils_1.assert(opts.min >= 0, 'Min cannot be less than zero.');
return this.integer(opts);
};
/**
* Given an array, pick a random element and return it
* @param array - The array to process
*
*/
BasicRandom.prototype.pickone = function (array) {
utils_1.assert(array.length !== 0, 'Cannot pickone() from an empty array');
return array[this.natural({ max: array.length - 1 })];
};
/**
* Given an array, pick some random elements and return them in a new array
* @param array - the array to process
* @param count - the counts to pick
*/
BasicRandom.prototype.pickset = function (array, count) {
if (count === void 0) { count = 1; }
if (count === 0)
return [];
utils_1.assert(array.length !== 0, 'Cannot pickset() from an empty array');
utils_1.assert(count >= 0, 'Count must be a positive number');
if (count === 1) {
return [this.pickone(array)];
}
var arr = array.slice(0);
var end = arr.length;
return this.n(function gen() {
end -= 1;
var index = this.natural({ max: end });
var value = arr[index];
arr[index] = arr[end];
return value;
}, Math.min(end, count));
};
/**
* Given an array, scramble the order and return it.
* @param array - the array to process
* @public
*/
BasicRandom.prototype.shuffle = function (array) {
var newArray = [];
var j = 0;
var length = array.length;
var sourceIndexes = utils_1.range(length);
var lastSourceIndex = length - 1;
var selectedSourceIndex;
for (var i = 0; i < length; i += 1) {
// Pick a random index from the array
selectedSourceIndex = this.natural({ max: lastSourceIndex });
j = sourceIndexes[selectedSourceIndex];
// Add it to the new array
newArray[i] = array[j];
// Mark the source index as used
sourceIndexes[selectedSourceIndex] = sourceIndexes[lastSourceIndex];
lastSourceIndex -= 1;
}
return newArray;
};
/**
* Provide any function that generates random stuff (usually another generate function)
* and a number and n() will generate an array of items with a length matching the length you specified.
* @param generator - the generator
* @param length - the length
* @param params - the generator's params
*
* @example
* ```javascript
* const R = new Random();
* R.n(R.natural, 10, { min: 0, max: 100 }); // ten numbers which arn between 0 and 100
* ```
*/
BasicRandom.prototype.n = function (generator, length) {
if (length === void 0) { length = 1; }
var params = [];
for (var _i = 2; _i < arguments.length; _i++) {
params[_i - 2] = arguments[_i];
}
utils_1.assert(typeof generator === 'function', 'The first argument must be a function.');
var i = length;
var arr = [];
// Providing a negative count should result in a noop.
i = Math.max(0, i);
for (; i > 0; i -= 1) {
arr.push(generator.apply(this, params));
}
return arr;
};
/**
* Generate a string which match regexp
*
* @example
* ```javascript
* new Random().randexp('\\d{4}-\\d{8}');
* ```
*
* @param source - regexp or source of regexp
* @param flag - flag(only support `i`)
*/
BasicRandom.prototype.randexp = function (source, flag) {
var rand = new randexp_1.default(source, flag);
return rand.gen();
};
return BasicRandom;
}());
exports.BasicRandom = BasicRandom;