From 04416eae185b803a963ce1bc191977d0fb85c6d6 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Tue, 5 Sep 2017 17:56:58 +0200 Subject: [PATCH] Adding randomString --- .travis.yml | 1 + README.md | 31 ++++++++++++++++-- index.js | 1 + package.json | 2 +- random-string.js | 64 ++++++++++++++++++++++++++++++++++++++ test.js | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 random-string.js diff --git a/.travis.yml b/.travis.yml index 8ea9c4a..fc55de6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,3 +4,4 @@ node_js: - "5" - "6" - "7" + - "8" diff --git a/README.md b/README.md index b0e8055..4c9ef0b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,8 @@ npm install --save pandemonium * [dangerousButPerformantSample](#dangerousbutperformantsample) * [naiveSample](#naivesample) * [random](#random) -* [randomIndex](#randomIndex) +* [randomIndex](#randomindex) +* [randomString](#randomstring) * [sample](#sample) * [shuffle](#shuffle) * [shuffleInPlace](#shuffleinplace) @@ -105,7 +106,7 @@ import {createRandom} from 'pandemonium/random'; const customRandom = createRandom(rng); ``` -## random +## randomIndex Function returning a random index of the given array. @@ -123,6 +124,32 @@ import {createRandomIndex} from 'pandemonium/random-index'; const customRandomIndex = createRandomIndex(rng); ``` +## randomString + +Function returning a random string. + +```js +import randomString from 'pandemonium/random-string'; +// Or +import {randomString} from 'pandemonium'; + +// To generate a string of fixed length +randomString(5); +>>> 'gHepM' + +// To generate a string of variable length +randomString(3, 7); +>>> 'hySf3' + +// To create your own function using custom RNG +import {createRandomString} from 'pandemonium/random-string'; + +const customRandomString = createRandomString(rng); + +// If you need a custom alphabet +const customRandomString = createRandomString(rng, 'ATGC'); +``` + ## sample Function returning a sample of size `k` from the given array. diff --git a/index.js b/index.js index 5fcf5ad..927a48e 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ module.exports = { naiveSample: require('./naive-sample.js'), random: require('./random.js'), randomIndex: require('./random-index.js'), + randomString: require('./random-string.js'), sample: require('./sample.js'), shuffle: require('./shuffle.js'), shuffleInPlace: require('./shuffle-in-place.js'), diff --git a/package.json b/package.json index a0dec46..4939a98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pandemonium", - "version": "1.1.0", + "version": "1.2.0", "description": "Typical random-related functions for JavaScript.", "main": "index.js", "scripts": { diff --git a/random-string.js b/random-string.js new file mode 100644 index 0000000..1197ec3 --- /dev/null +++ b/random-string.js @@ -0,0 +1,64 @@ +/** + * Pandemonium Random String + * ========================== + * + * Function generating random strings. + */ +var createRandom = require('./random.js').createRandom; + +/** + * Constants. + */ +var DEFAULT_ALPHABET = ( + 'abcdefghijklmnopqrstuvwxyz' + + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + '0123456789' +); + +/** + * Creating a function returning a random string composed from characters of + * the given alphabet. + * + * @param {function} rng - RNG function returning uniform random. + * @param {string|array} alphabet - Target alphabet. + * @return {function} - The created function. + */ +function createRandomString(rng, alphabet) { + if (!alphabet) + alphabet = DEFAULT_ALPHABET; + + var customRandom = createRandom(rng), + randomCharacterIndex = customRandom.bind(null, 0, alphabet.length - 1); + + /** + * Random string function. + * + * @param {number} length - Desired string length. + * @return {number} + */ + return function(length) { + if (arguments.length > 1) { + + // We want to generate a string of variable length + length = customRandom(arguments[0], arguments[1]); + } + + var characters = new Array(length); + + for (var i = 0; i < length; i++) + characters[i] = alphabet[randomCharacterIndex()]; + + return characters.join(''); + }; +} + +/** + * Default random string using `Math.random`. + */ +var randomString = createRandomString(Math.random); + +/** + * Exporting. + */ +randomString.createRandomString = createRandomString; +module.exports = randomString; diff --git a/test.js b/test.js index e448d36..94ea595 100644 --- a/test.js +++ b/test.js @@ -393,3 +393,84 @@ describe('#.createCachedWeightedChoice', function() { }); }); }); + +describe('#.createRandomString', function() { + var createRandomString = lib.randomString.createRandomString; + + it('should be able to produce random string of fixed length.', function() { + var randomString = createRandomString(rng()); + + var tests = [ + '', + 'w', + 'os', + 'CFq', + 'DRw', + '9TLYZ', + 'QD02aP', + 'VXNLajS', + 'l07VLFXK' + ]; + + var results = tests.map(function(s) { + return randomString(s.length); + }); + + assert.deepEqual(results, tests); + }); + + it('should be able to produce random string of variable length.', function() { + var randomString = createRandomString(rng()); + + var tests = [ + [0, 0, ''], + [0, 2, ''], + [0, 3, 'C'], + [0, 3, 'qD'], + [0, 3, 'w9'], + [0, 10, 'LYZQD02a'], + [4, 7, 'VXNLaj'], + [5, 5, 'l07VL'], + [3, 14, 'XKuVG2i18'] + ]; + + var results = tests.map(function(s) { + return randomString(s[0], s[1]); + }); + + assert.deepEqual(results, tests.map(function(s) { + return s[2]; + })); + + var batch = new Array(1000); + + for (var i = 0; i < 1000; i++) + batch[i] = randomString(3, 14); + + assert(batch.every(function(s) { + return s.length >= 3 && s.length <= 14; + })); + }); + + it('should produce random strings based on a custom alphabet.', function() { + var randomString = createRandomString(rng(), 'ATGC'); + + var tests = [ + '', + 'T', + 'AT', + 'TGT', + 'TGT', + 'CGGCC', + 'GTCCAG', + 'CCGGAAG', + 'ACCCGGCG' + ]; + + var results = tests.map(function(s) { + return randomString(s.length); + }); + + assert.deepEqual(results, tests); + }); +});