How to shuffle an array
Short answer
The Fisher-Yates algorithm goes from the end and swaps each element with a random one before it:
const shuffle = (array) => {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
};
const cards = ['A', 'K', 'Q', 'J', '10'];
const shuffled = shuffle(cards);
console.log(shuffled.length, [...shuffled].sort().join(''));Output:
5 10AJKQCommon mistake
The popular sort(() => Math.random() - 0.5) looks shorter, but it mixes unevenly: some orders come out much more often than others. Count how often the first element stays in place:
let stays = 0;
for (let i = 0; i < 10000; i++) {
const result = [1, 2, 3, 4, 5].sort(() => Math.random() - 0.5);
if (result[0] === 1) stays++;
}
console.log(stays > 2000 ? 'more often than 1 in 5' : 'about 1 in 5');Output:
more often than 1 in 5With an even shuffle the first element stays in place in about one case out of five.
Functions used in this recipe
- Math.random — Returns a random number between 0 and 1.
- Math.floor — Rounds a number down to an integer.