Logo

How to randomize (shuffle) a JavaScript array?

Shuffling an array randomly is a common task in JavaScript—useful for card games, randomized surveys, or anytime you need to present elements in unpredictable order. The most reliable technique is the Fisher–Yates (Knuth) Shuffle, which produces a uniformly random permutation in O(n) time. Below, we’ll explore how to implement it, discuss alternative approaches, and share tips to ensure you write bug-free, performant code.

Fisher–Yates (Knuth) Shuffle Algorithm

This algorithm randomly swaps elements from the end of the array moving backward, ensuring each element has an equal probability of landing in any position.

function shuffleArray(arr) { // Create a copy if you need immutability; otherwise, modify in place for (let i = arr.length - 1; i > 0; i--) { // Generate a random index from 0 to i const j = Math.floor(Math.random() * (i + 1)); // Swap elements at i and j [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } // Example usage: const numbers = [1, 2, 3, 4, 5]; console.log(shuffleArray(numbers)); // Possible output: [4, 1, 5, 2, 3]
  • Explanation:
    1. We iterate backward from the last element to the second element (index arr.length - 1 down to 1).
    2. For each position i, generate a random index j between 0 and i.
    3. Swap elements at positions i and j.
  • Uniformity: Every permutation is equally likely, making this a statistically sound approach.

Alternative Approaches (And Why to Avoid Them)

  1. Random Sort Trick

    arr.sort(() => Math.random() - 0.5);
    • Although short, this method does not guarantee a uniform distribution and can be less performant.
    • Use it only for quick experiments or non-critical cases.
  2. Libraries

    • You could rely on utility libraries like Lodash (_.shuffle), but internally they often use a version of the Fisher–Yates shuffle anyway.

Performance Considerations

  • Time Complexity: The Fisher–Yates shuffle runs in O(n) time. You only make one pass through the array, performing a constant amount of work per element (just one swap).
  • Space Complexity: In-place shuffling is O(1) in extra space. If you make a copy of the array before shuffling, that’s an additional O(n) space cost.

Practical Tips and Interview Insights

  1. Immutability: If you need to avoid mutating the original array (for instance, in React state management), create a copy before performing the shuffle.
  2. Randomness Discussion: In an interview, note that Math.random() may have limitations and biases depending on the environment, but for most front-end or general back-end tasks, it’s sufficient.
  3. Edge Cases: Handle arrays with zero or one element gracefully (though Fisher–Yates naturally covers that by never entering the loop).

Expand Your JavaScript Expertise

To strengthen your JavaScript fundamentals and coding interview skills, consider these resources from DesignGurus.io:

And if you’re ready for a trial run, book a Coding Mock Interview to get real-time feedback from ex-FAANG engineers.

Conclusion

Shuffling an array might sound straightforward, but the correct approach—the Fisher–Yates algorithm—ensures true uniform randomness and efficiency. Whether you’re preparing for technical interviews or building production-grade features, knowing how to implement and optimize a reliable shuffle is a crucial skill in JavaScript development. Happy coding!

CONTRIBUTOR
TechGrind