Recently I needed to be able to get a random element from an array. It was slightly surprising to me that the Javascript Array class doesn’t provide a built-in function for that.

In this post I talks about how I built a function to do that and also compared with the `_.sample`

function from the popular Javascript library lodash.

## Initial Implementation

I’m building it in Typescript, since the project I am working on already uses Typescript.

The function takes an array and returns a random element from it. The type of array element doesn’t matter here. So the function signature should be something like this:

```
(arr: any[]) => any
```

For an array, the lowest valid index is `0`

and the highest valid index is `arr.length - 1`

. I could generate an random integer between `0`

and `arr.length - 1`

. Then if I use that number as index for the array, I could get back a random element. That should look like this:

```
Math.floor(Math.random() * arr.length)
```

So we have our function:

```
const getRandomElement = (arr: any[]) =>
arr[Math.floor(Math.random() * arr.length)]
```

It does the job and it’s fairly straightforward. But there is actually a small issue, which I’ll address in later.

## Comparison with `_.sample`

After implementing it, I thought that there is a `_.sample`

function from the popular library lodash, it would be interesting to see how it was implemented.

I’m going to look at the latest version of lodash, which is 4.17.21 as of this writing.

The `_.sample`

function looks like this:

```
/**
* Gets a random element from `collection`.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Collection
* @param {Array|Object} collection The collection to sample.
* @returns {*} Returns the random element.
* @example
*
* _.sample([1, 2, 3, 4]);
* // => 2
*/
function sample(collection) {
var func = isArray(collection) ? arraySample : baseSample;
return func(collection);
}
```

Apparently it handles not only arrays but also collections in general.

I won’t worry about `baseSample`

for collections that are not array in this article. But if you like, feel free to check out its source.

For arrays, it delegates to a `arraySample`

function, which looks like this:

```
/**
* A specialized version of `_.sample` for arrays.
*
* @private
* @param {Array} array The array to sample.
* @returns {*} Returns the random element.
*/
function arraySample(array) {
var length = array.length;
return length ? array[baseRandom(0, length - 1)] : undefined;
}
```

So it checks the array length, and if length is `0`

it returns `undefined`

. Otherwise it’s very similar to my implementation: it calls `baseRandom`

with `0`

and `length - 1`

to (presumably) get a random integer, then use it as index for the array and gets a random element from the array.

In order for this to work, the `baseRandom`

function must generate a random integer between its two arguments.

```
/**
* The base implementation of `_.random` without support for returning
* floating-point numbers.
*
* @private
* @param {number} lower The lower bound.
* @param {number} upper The upper bound.
* @returns {number} Returns the random number.
*/
function baseRandom(lower, upper) {
return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
}
```

And looks like it does!

`nativeFloor`

and `nativeRandom`

in here are just aliases for the built-in methods `Math.Floor`

and `Math.random`

.

## Improvement

I’m glad to see that the core logic of `_.sample`

for arrays is very similar to the `getRandomElement`

function I got. However, it did check the array length, which I forgot to do.

In my use case, `getRandomElement`

is just used as a test helper and the same non-empty array constant is always passed in, so omitting the array length check isn’t causing any issue for now.

But for completeness’ sake and also to allow it to be used in other scenarios in the future, I should add the array length check. So the function becomes:

```
const getRandomElement = (arr: any[]) =>
arr.length ? arr[Math.floor(Math.random() * arr.length)] : undefined
```

## Summary

In this article, I walked through how to implement a function for getting a random element from an array, had a tour in lodash source code around `_.sample`

and improved the initial implementation by adding an array length check to make it more complete and robust.

Open source not only come in handy when we need to use them directly in our projects, but also serve as a great resource for learning.

I definitely should look more into source code of open source libraries and frameworks. Maybe you should too

## Leave a comment