In-Depth Guide to Shuffle Any Type of JavaScript Array

Robin
May 7, 2022

Shuffling an array is a common question asked in coding interviews. There is a couple of different ways to shuffle an array in JavaScript.

To shuffle an array means randomizing the order of the items by putting them in different positions within the array. In this way, items in an array reposition themselves by changing their indexes.

Whenever you want to shuffle or randomize an array, you have to generate a random index for each item of that array.

There are the following methods you can use to mix up an array in JavaScript:

  1. Fisher-Yates shuffle algorithm in JavaScript.
  2. Apply Array.sort() method to randomize an array in JavaScript.
  3. Use Array.map() with the Array.sort() method to get a shuffled array.

In this article, I will walk you through different methods to shuffle or randomize a JavaScript array step by step with their pros and cons.

Also Read: How to Remove Elements From an Array in JavaScript

Shuffle a JavaScript Array Using Fisher-Yates Algorithm

Among different methods, the Fisher-Yates shuffle algorithm is better in terms of performance and reliability. This algorithm reorganizes an array in more random order.

Shuffle a JavaScript Array Using Fisher-Yates Algorithm

It is a simple algorithm that loops over the array in reverse order and swaps each element with a random one in the array. You can do this in just 4 steps:

  1. Loop over the array to select each element.
  2. Generate a random index using Math.random() method.
  3. Store the value of the current array item in a new variable.
  4. Swap the current array item with the randomly generated item.

Let’s see each step in detail with an example.

Step 1: In this example, I have created a function called shuffle() that accepts an array as its argument. Inside the function, I am looping over the array using the for loop.

const shuffle = (array) => {
    for (let i = array.length - 1; i > 0; i--) {
        // step 2
        // step 3
        // step 4
    }
};

This for loop will go through all items in reverse order.

Step 2: I am generating a random index that ranges between 0 to i (current item index). I am storing that random index in the j variable.

const shuffle = (array) => {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        // step 3
        // step 4
    }
};

Step 3: I am storing the current item in the temp variable using the array[i] to swap it with the random item.

const shuffle = (array) => {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        const temp = array[i];
        // step 4
    }
};

Step 4: Finally, I am swapping items array[i] and array[j] with each other. Put randomly generated item at index i and put the current item in the loop at index j.

const shuffle = (array) => {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        const temp = array[i];
        
        // Swap
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
};

After completing all these steps, I am returning the shuffled array from the function after completing the for loop.

Now you can use this function to shuffle any type of JavaScript array.

I have created an array of numbers. It doesn’t have to be a number array. You can use strings or objects as well.

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffle(values));
// [3, 8, 1, 9, 5, 2, 10, 7, 4, 6]

When I pass the array in the shuffle() function, it returns a shuffled array.

Also Read: JavaScript Constructor Function Explained with Examples

Write Fisher-Yates Algorithm With JavaScript ES6 Syntax

You can implement the Fisher-Yates shuffle algorithm with the JavaScript ES6 syntax if you want without using the for loop.

const shuffleES6 = (array) => {
    array.reverse().forEach((item, index) => {
        const j = Math.floor(Math.random() * (index + 1));
        [array[index], array[j]] = [array[j], array[index]];
    });

    return array;
};

In this example, I am using ES6 syntax. With the Array.reverse() method, I am reversing the array. Then I loop over the reversed array using Array.forEach() method.

Inside the callback function, we automatically get the current array item and its index. So, you just have to generate a random index to select another item from the array.

After randomly selecting the second item, you can swap them using the array spread operator in JavaScript.

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffleES6(values));
// [7, 3, 1, 5, 10, 2, 6, 8, 4, 9]

When you call the shuffleES6() function with an array, it will also return a shuffled array. Now it’s up to you which syntax you want to use in your application.

Shuffle a JavaScript Array Using The sort() Method

If you want a simple way to reorganize your JavaScript array without using the Fisher-Yates algorithm, you can use the built-in JavaScript array sort() method.

const shuffle = (array) => {
    return array.sort(() => 0.5 - Math.random());
};

I am also creating a shuffle() function that accepts an array in its argument. I will apply sort() method to this array to randomize it.

This method takes a callback function. And you must return a positive or a negative number from that callback function.

The sort() method swaps one item with the next item in an array depending on the returned value from its callback function.

Shuffle a JavaScript Array Using sort() Method

To return a number, I am generating a random number between 0 to 1 with the Math.random() method.

Then I subtract that random number from 0.5 and return it from the callback function. In this way, you can generate randomly generate a positive or a negative number each time.

If the Math.random() method generates a number greater than 0.5 then the callback function will return a negative number. If it generates a number smaller than 0.5 then the callback function will return a positive number.

For example, if the Math.random() method gives 0.75 and after subtracting it from 0.5 you will get -0.25 which is a negative number.

On the other hand, if the Math.random() method gives 0.3 and after subtracting if from 0.5 you will get 0.2 which is a positive number.

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffle(values));
// [7, 6, 10, 5, 4, 8, 9,  3, 2, 1]

Fisher-Yates Algorithm VS Array.sort() Method

Even if both methods can shuffle an array in JavaScript, the Fisher-Yates algorithm can mix up an array more efficiently than the sort() method.

Because the Array.sort() method only swaps 2 side by side items in an array. On the other hand, the Fisher-Yates algorithm can swap one item with any other item in the array.

That’s why this algorithm can return a more shuffled array compared to the Array.sort() method in JavaScript.

// Fisher-Yates shuffle algorithm
[2, 6, 10, 1, 5, 3, 9, 7, 4, 8]
[7, 1, 9, 8, 4, 3, 2, 10, 6, 5]
[10, 7, 4, 5, 3, 6, 8, 1, 9, 2]

// Array.sort() method
[4,  8, 2, 1, 3, 9, 10, 5, 6, 7]
[3, 4, 9,  6, 7, 8, 2, 1, 10, 5]
[6, 5, 3, 4, 8,  10, 7, 9, 1, 2]

After running both methods a couple of times, we can see the difference. The Fisher-Yates algorithm is returning a more shuffled array each time.

If you want a simple way to rearrange your JavaScript array and you don’t need a more shuffled array then you can use the sort() or map() method.

But if you need a more randomized array each time then go with the Fisher-Yates shuffle algorithm to mix up your JavaScript array.

Also Read: Best Guide on Dynamic Import in JavaScript for Importing Modules

Shuffle an Array in JavaScript Without Changing The Original Array

If we look into both methods shown in the previous sections for the Fisher-Yates algorithm and Array.sort() method, you will see both of them modify the original array.

const shuffleES6 = (array) => {
    array.reverse().forEach((item, index) => {
        const j = Math.floor(Math.random() * (index + 1));
        [array[index], array[j]] = [array[j], array[index]];
    });

    return array;
};

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffleES6(values));
// [9, 5, 1, 8, 10, 2, 6, 7, 3,  4]

console.log(values);
// [9, 5, 1, 8, 10, 2, 6, 7, 3,  4]

In this example, we can see if we call the shuffleES6() method, it returns a shuffled array. But after that, it also changes the original array.

The same thing happens with the Array.sort() method. If you don’t want this behavior, you can easily change it by just adding one line of code.

Solution:

// Fisher-Yates Shuffle Algorithm

const shuffleES6 = (array) => {
    const newArray = [...array];

    newArray.reverse().forEach((item, index) => {
        const j = Math.floor(Math.random() * (index + 1));
        [newArray[index], newArray[j]] = [newArray[j], newArray[index]];
    });

    return newArray;
};

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffleES6(values));
// [5, 7, 10, 2, 4, 1, 9, 3, 8, 6]

console.log(values);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

To keep the original array unchanged, you have to make a new copy of the array using the spread operator in JavaScript.

Inside the shuffleES6() function, I am creating a copy of the original array and storing it in the newArray variable.

Instead of using the original array, you have to use the copied array to shuffle. Finally, you will return the copied array from the function.

// Array.sort() method

const shuffle = (array) => {
    const newArray = [...array];
    return newArray.sort(() => 0.5 - Math.random());
};

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffle(values));
// [3, 2, 4, 1, 9, 7, 5, 6, 8, 10]

console.log(values);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

You can do the same with the Array.sort() method. This time it will return a shuffled array without modifying the original array.

Shuffle an Array in JavaScript With map() Method

You can randomize a JavaScript array using the map() method. In this technique, we need to use both map() and sort() methods together.

Let’s see how it is done.

const shuffle = (array) => {
    return array
        .map((item) => ({ sort: Math.random(), value: item }))
        .sort((a, b) => a.sort - b.sort)
        .map((item) => item.value);
};

Total 3 steps are required to complete this process. These steps are:

1. Generate an array of objects: The first map() method will loop over the array and will return a new array of objects. Inside this array, each object will have 2 properties, sort and value.

The sort property contains a random number between 0 to 1 generated by Math.random() method. The value property contains the actual item from the original array.

2. Shuffle the array of objects: The sort() method will shuffle the array of objects generated by the previous map() method according to the returned value from the callback function.

It will return a positive or a negative value by subtracting 2 sort properties from 2 objects. As the number in the sort property is generated randomly, subtracting will also return a positive or a negative number randomly.

3. Get the original array from the array of objects: The second map() method will loop over the shuffled array of objects and will return a new array with the value properties. It will remove the sort property.

Therefore, the new array will only contain items of the original array but in random order.

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(shuffle(values));
// [5, 1, 8, 9, 7, 4, 2, 6, 3, 10]

console.log(values);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

When I call the shuffle() function with an array, it returns a shuffled array. But if you notice, the original array didn’t change this time.

Because the map() method always returns a new array. When the first map() method was called, it returned a new array and then the sort() method shuffled that new array, not the original one.

Therefore, this technique by default doesn’t modify the original array.

Also Read: Input VS Change VS Blur VS Focus – Differences of JavaScript Events

How to Shuffle an Array of Objects in JavaScript

All the techniques, I have shown previously will shuffle any type of JavaScript array. The array may contain numbers, strings, objects, or any other types. It does not matter.

So, you don’t have to do anything in order to shuffle an array of objects. Pass an array of objects to those functions and they will shuffle your array.

const shuffle = (array) => {
    const newArray = [...array];

    newArray.reverse().forEach((item, index) => {
        const j = Math.floor(Math.random() * (index + 1));
        [newArray[index], newArray[j]] = [newArray[j], newArray[index]];
    });

    return newArray;
};

const products = [
    { name: 'cucumber', type: 'vegetable' },
    { name: 'banana', type: 'fruit' },
    { name: 'celery', type: 'vegetable' },
    { name: 'apple', type: 'fruit' },
    { name: 'orange', type: 'fruit' },
    { name: 'carrot', type: 'vegetable' },
];

console.log(shuffle(products));

Output:

[                                          
  { name: 'carrot', type: 'vegetable' },   
  { name: 'banana', type: 'fruit' },       
  { name: 'celery', type: 'vegetable' },   
  { name: 'cucumber', type: 'vegetable' }, 
  { name: 'orange', type: 'fruit' },       
  { name: 'apple', type: 'fruit' }         
]

In this example, I am using the Fisher-Yates algorithm. But the Array.sort() and Array.map() methods will also shuffle array objects.

Shuffle a JavaScript Array With an External Library

You can use an external NPM library like Lo-Dash to shuffle an array. This library has a function that will directly randomize your array without writing any algorithm.

Run the following command to initialize a Node.js project.

npm init -y

It will generate a package.json file in the root of your project folder. This file will list all the installed packages in your project.

Also Read: Best Setup to Use TypeScript with Node.js and Express Project

Now, install the lodash library with the following command:

npm install --save lodash

This library provides a shuffle() function to shuffle an array in JavaScript. You just have to import and call it with an array.

This function uses the Fisher-Yates shuffle algorithm under the hood.

const _ = require('lodash');

const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(_.shuffle(values));
// [5, 8, 9, 2, 4, 1, 7, 10, 3, 6]

console.log(values);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

This function doesn’t modify the original array. It also can shuffle an array of objects.

const _ = require('lodash');

const products = [
    { name: 'cucumber', type: 'vegetable' },
    { name: 'banana', type: 'fruit' },
    { name: 'celery', type: 'vegetable' },
    { name: 'apple', type: 'fruit' },
    { name: 'orange', type: 'fruit' },
    { name: 'carrot', type: 'vegetable' },
];

console.log(_.shuffle(products));

Output:

[                                                      
  { name: 'orange', type: 'fruit' },                   
  { name: 'celery', type: 'vegetable' },               
  { name: 'banana', type: 'fruit' },                   
  { name: 'carrot', type: 'vegetable' },               
  { name: 'cucumber', type: 'vegetable' },             
  { name: 'apple', type: 'fruit' }                     
]

Conclusion

There are multiple ways to shuffle a JavaScript array. Just for this one purpose installing a library is not a good idea. Because external libraries like Lo-Dash contain many many functions.

So, their size also becomes large. If you need other features that these libraries offer then it’s good to use them. Because it will save you a lot of time.

Otherwise, you can write your own function easily that will randomize your array. In this way, your application will have less unnecessary code.

That’s why in this article, I have shown you the most used techniques to shuffle a JavaScript array.

I hope it was helpful for you. Thank you so much for reading. Happy coding!

Related Posts