Avoid shuffling with .sort(() => Math.random() — 0.5))
Tags: javascript, typescript, webdev, programming
Published: 2024-01-19 07:32:20

> Cover Image by <a href="https://pixabay.com/users/adinavoicu-485024/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=1339690">Adina Voicu</a> from <a href="https://pixabay.com//?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=1339690">Pixabay</a>

Searching online for shuffling an array in JS you will find multiple solutions. I wanted to compare the three of them for fairness and speed.

To test the fairness I shuffled 100,000 lists of 100 elements. Next, I used a heat map to look for a relation between the starting position and the position after shuffling. Ideally, there is none. This is not a static analysis but an easy insight into bias and to find out where the bias might be.

## Sort with random

While searching for a shuffle method, I came across this beautiful one-liner; the worst one in this list: [StackOverflow answer](https://stackoverflow.com/a/53066842/4333982). And foolishly used it for the game [Where the Flag is This](http://www.wheretheflagisthis.com/)!
```js
yourArray.sort(() => Math.random() - 0.5))
```
## Fairness

Looking at the heat map below we find the fairness to be poor. If something starts at position 0 it is twice as likely to end up in position 0 after shuffling compared to fair. While elements 1 and 51 have almost no chance of becoming one of the last elements.

![Heatmap showing the fairness of the first method](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p29wabzs0yk7wmrp7y3k.png)


{% gist https://gist.github.com/wagenrace/16502729420dfb64663fdb7155f99acb.js %}
## Speed

The speed is a bit harder to determine because of the use of sort. JS will have different sorting algorithms depending on the engine you use. So Firefox and Chrome can have different results. But sorting algorithms are most likely O(n²) or O(n log(n)).
Not the worst but it’s also not great given we only want to shuffle.

## Sort by random value

A slightly better idea is to give each number a random value and then sort based on this random value.

## Fairness

The fairness looks as good as you will get. No matter the starting position you can end up anywhere.

![Heatmap showing the fairness of the second method](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/culgfktng2e1ysky5h42.png)
{% gist https://gist.github.com/wagenrace/47ec2d0acb00c98c8dd9e902ae7f1b4d.js %}
## Speed

The speed is determined by sort. So most likely O(n²) or O(n log(n)).

## Fisher-Yates

Maybe AI will help us, let’s ask ChatGPT, and it gives us the [Fisher-Yates](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) shuffle. This algorithm you will also find on [Stackoverflow](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) most of the time.

![A conversation with chatGPT to ask for a shuffle function in javascript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ss4titez47xjz93uxvtq.png)

Screenshot of ChatGPT, where ChatGPT is asked to give a JavaScript shuffle algorithm and it returns a JavaScript function with the Fisher-Yader shuffle.

## Fairness

Once again perfect fairness to the human eye. To repeat: This is not a static analysis just a visualization of the bias.


![Heatmap showing the fairness of the Fisher-Yader shuffle method](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lkpz6ywote6lrvzjbx0f.png)
{% gist https://gist.github.com/wagenrace/69aaa68b2415feebff5ae458f89e768e.js %}
## Speed

We go through a for-loop with no loops inside it, meaning we only do 1 action per item in the list. This gives us an O(n). The best speed we could have.

## Conclusion

Use Fisher-Yader if you need to shuffle a list!