randomator

composable random generators

Usage no npm install needed!

<script type="module">
  import randomator from 'https://cdn.skypack.dev/randomator';
</script>

README

Randomator

Composable, Iterable, and transformable random value generators.

Intro

A Randomator is a random value generator. A Randomator may be constructed using the new Randomator constructor but more often they are constructed using the supplied generators and operators described below. Every Randomator is a function and an iterable that returns a new value each time. Some interesting things about Randomators are:

  • A Randomator is a function that returns a new random value each time it is called.
  • A Randomator is an iterable and can be used in a for-of loop.
  • A Randomator can be transformed using the .map and .filter operators.

As an base example we will create a Randomator that returns a random integer between 0 and 1:

const number$ = new Randomator(() => Math.random());

Note: in this readme I'll use Finnish Notation to signify a Randomator instance. This is simply for clarity.

The Randomator constructor takes a function that returns a new value each time it is called. Since a Randomator is a function it can be called to return a value:

console.log(number$());  // prints a random number between 0 and 1 (same as Math.random())

A Randomator is also an iterable and can be used in a for-of loop:

let count = 0;
for (const number of number$) {
  if (count++ > 10) break;
  console.log(number);
}

Warning: Use caution when using a Randomator in a for-of loop... it is an infinite stream of values!

A Randomator can be transformed using the .map and .filter operators:

const numbers$ = new Randomator(() => Math.random());
const integers$ = numbers$.map(number => Math.floor(number * 100));
const evenIntegers$ = integers$.filter(number => number % 2 === 0);

Warning: Use caution when using filter, a strict predicate may cause an infinite loop.

These derived Randomators are lazy; meaning that no generation takes place until the Randomator is called.

While Randomators can be created using the new Randomator constructor, they are more often created using the built-in operators:

const number$ = numbers();
console.log(number$());  // Prints an random number (same as Math.random())

A more involved example is the string function which take several options and returns a Randomator of strings:

const chars$ = chars({ pool: 'abc' });
const length$ = integers({ min: 3, max: 13 });
const string$ = strings({ chars: chars$, length: length$ }); // A randomator that generates string between three (3) and 13 characters (inclusive) of 'a', 'b' or 'c'.

And operators:

const number$ = numbers();
const evenNumber$ = number$.filter(number => number % 2 === 0);
const oddNumber$ = number$.filter(number => number % 2 !== 0);
const oddEven$ = tuple(oddNumber$, evenNumber$);  // A randomator that generates odd/even pairs

Built-in Generators

Numbers

numbers

Generates a number between 0 and 1 (inclusive of 0, but excluding 1). This Randomator is basically a wrapper around Math.random.

const number$ = numbers();
number$();  // [0, 1) same as `Math.Random`

floats

Generates a number between min and max rounded to fixed decimal places (default: { min: 0, max: 1, fixed: 4 }) inclusive of min, but not max.

const float$ = floats();
float$();  // [0, 1)

const otherFloat$ = floats({ min: -1e10, max: 1e10, fixed: 0 });
otherFloat$();  // [-1e10, 1e10)

integers

Generates a integer between min and max (default: { min: 0, max: 9 }) inclusive of min and max.

integers()();  // [0, 9] (aka a single digit)
integers({ min: 5, max: 12 })();  // [5,12]

Strings

chars

chars()();  // returns a random character (one of `abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()`).
chars({ pool: '!@#

 })();  // returns a random character from the set '!@#


strings

strings()();  // returns a random string with between 5 and 20 lowercase characters.
strings({ length: 5 })();  // returns a string of five lowercase characters.

const chars$ = chars({ pool: 'abc' });
const length$ = integers({ min: 3, max: 13 });
const string$ = strings({ chars: chars$, length: length$ });
console.log(string$());  // Prints a string between three (3) and 13 characters (inclusive) of 'a', 'b' or 'c'.

Dates

dates

dates()();  // returns a date between Sep 14 1752 and Apr 18 2187
dates({ min: new Date('1/1/1970'), max: new Date('1/1/2020') })();  // returns a string between 1 Jan 1970 and 1 Jan 2020

past

past()();  // returns a date between Sep 14 1752 and now
past({ min: new Date('1/1/1970') })();  // returns a string between 1 Jan 1970 and now

future

future()();  // returns a date between now invoked and Apr 18 2187
future({ max: new Date('1/1/2020') })();  // returns a string between now and 1 Jan 2020

Operators

Operators are functions which can be called to create a new Randomators.

oneOf

const yesNoMaybe$ = oneOf(['yes', 'no', 'maybe']);
yesNoMaybe$(); // returns one random value from the input array

tuple

const integer$ = integers();
const string$ = strings();
const tuple$ = tuple([integer$, string$]);
tuple$();  // returns an array (equivalent to [integer$(), string$()])

array

const string$ = strings();
array(string$, 3)();  // returns an array of three (3) random strings
integer({ min: 0, max: 6 }).map(length => array(string$, length)();  // returns an array of between three (3) and six (6) random strings

seq

const name$ = string().map(capitalize);
const age$ = integer({ min: 0, max: 12 });
const phrase$ = seq([name$, ' is ', age$]);
phrase$();  // returns a random string like `{string} is {integer}`

randomator Tag Function

A randomator tagged template function which is essentially a wrapper around the seq operator:

const name$ = strings().map(capitalize);
const age$ = integers({ min: 0, max: 12 });
const phrase$ = randomator`${name$} is ${age$}`;
phrase$();  // same as seq([name$, ' is ', age$])();

License

This project is licensed under the MIT License - see the LICENSE file for details