# Better Randomization Support in JS

**URL:** <https://es.discourse.group/t/better-randomization-support-in-js/1502>\
**Category:** 💡 Ideas\
**Created:** [November 6, 2022, 12:46am UTC](https://es.discourse.group/t/better-randomization-support-in-js/1502 "2022-11-06T00:46:00Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [November 6, 2022, 12:46am UTC](https://es.discourse.group/t/better-randomization-support-in-js/1502/1 "2022-11-06T00:46:00Z")

</div>

I've seen a few of these threads, but none that covers all the aspects of randomization I struggle with.  
Randomization in JavaScript is very frustrating, and sometimes unusably slow (e.g. generating white noise or RGB noise). There is room for improvement here.

I usually find myself adding these functionalities:

- Balanced random.

```javascript
randomFloat = () => Math.random()*2 - 1;

```

- Random range.

```javascript
randomRange = ( start, end ) => start + Math.random() * (end-start);

```

- Random integer.

```javascript
randomInt = ( start, end ) =>
    parseInt( start + Math.random()*(end-start) );

```

- Seeded randomization. (Mulberry32 is my concise habit here.)

```javascript
seededRandom = seed =>
    ( t = ( seed += 0x6D2B79F5 ) ) => (
        t = Math.imul( t ^ t >>> 15, t | 1 ),
        t ^= t + Math.imul( t ^ t >>> 7, t | 61 ),
        ( ( t ^ t >>> 14 ) >>> 0 ) / 4294967296
    )

```

- Random array element selection.

```javascript
randomArrayElement = array =>
    array[parseInt( Math.random() * array.length )];

```

- Random object value selection. (Very inefficient!)

```javascript
randomObjectValue = ( object, keys = Object.keys( object ) ) =>
    object[keys[ parseInt( Math.random() * keys.length )] ];

```

(I have similar problems for Set and Map that similarly require generating and throwing away an array with every single call.)

- Filling a TypedArray with random data.

```javascript
/* (Use WebGL or WASM. Too long to demo here.) */

```

**But Most Crucially!**  
With iterator definitions, no standard interface exists for querying a "random" selection from the iterator's sequence.  
(Obviously not all iterators could or should define a random-from-sequence selection interface, but in the cases where I need it, I have to avoid iterators completely. That requires tremendous foresight during planning, which makes it easier to simply avoid iterators from the start.)

Would it be possible to generally address JavaScript's problems with randomization?

**Edit:**

Is my question too abstract? I could make a suggestion. Something like:

```javascript
Random.int( 0, 42 ); //maybe returns 33

var a = new Set( [1,2,3,5] );
Random.entryFrom( a ); //maybe returns 2

var b = { "x":11, "y":22, "z":33 }
Random.entryFrom( b ); //maybe returns ["z",33]

```

Random could handle arrays, strings, shuffling, statistical distributions... I don't know. Whatever makes most sense and would be used most.  
For iterators, there might be a `[@@random]()` or `[@@randomSkip]()` symbol or some such that `Random.entryFrom()` could attempt to call, perhaps?

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [November 6, 2022, 10:29am UTC](https://es.discourse.group/t/better-randomization-support-in-js/1502/2 "2022-11-06T10:29:57Z")

</div>

> [@0X-JonMichaelGalindo](#):
>
> Filling a TypedArray with random data.

There is [Crypto: getRandomValues() method - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for this particular one.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [November 6, 2022, 1:17pm UTC](https://es.discourse.group/t/better-randomization-support-in-js/1502/3 "2022-11-06T13:17:40Z")

</div>

> [@0X-JonMichaelGalindo](#):
>
> - Random integer.
> 
> - Random array element selection.

Don't use `parseInt` on numbers. It is meant to parse strings containing digits, and using it on numbers is very inefficient and slow. Use `Math.floor` for the same effect:

```javascript
randomInt = ( start, end ) =>
    Math.floor( start + Math.random()*(end-start) );
randomArrayElement = array =>
    array[Math.floor( Math.random() * array.length )];

```

> [@0X-JonMichaelGalindo](#):
>
> **But Most Crucially!**  
> With iterator definitions, no standard interface exists for querying a "random" selection from the iterator's sequence.

It's easy to see why: iterators do not have a known length. The best you could do is some kind of geometric progression of probabilities, and still there's always some probability to get no value if choosing a value behind the end of the iterator (100% for an empty iterator).

If you do know the expected length of the generated sequence, and want to choose one element with equal probability, you can just do

```javascript
randomArrayElement(iterator.toArray())

```

or

```javascript
iterator.drop(randomInt(expectedLength)).next().value

```

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [November 6, 2022, 1:32pm UTC](https://es.discourse.group/t/better-randomization-support-in-js/1502/4 "2022-11-06T13:32:56Z")

</div>

That does not work for floats, and offers no control. If there were helpful ways of addressing the majority of use cases, I would not find randomization "frustrating".

---

<div class="post-metadata">

**Author:** ![0X-JonMichaelGalindo](https://avatars.discourse-cdn.com/v4/letter/0/4af34b/32.png) [@0X-JonMichaelGalindo](https://es.discourse.group/u/0X-JonMichaelGalindo)\
**Post date:** [November 6, 2022, 1:45pm UTC](https://es.discourse.group/t/better-randomization-support-in-js/1502/5 "2022-11-06T13:45:00Z")

</div>

Please do not nitpick the demo code. I am saying that none of this should be implemented in user JS at all.

You misunderstood the iterator problem. I do not want an algorithm that messes with my iterators, I want an _interface_ that lets me implement my own algorithm.

Imagine if arrays or strings only allowed linear access. How useless would they be? Right now in JS, Objects, Sets, Maps, and Iterators all have that exact limitation.

`for in/of` is the only syntax that exists for accessing the elements of an Object, Set, Map, or Iterator. Selecting a random element requires allocating memory for a new array, copying values to it, accessing a random element of the array, then disposing of the array (or installing a mutation watcher on every operation performed on the target to dispose of the array if the target changes). It's inefficient.
