til/
← back to the board

2026-07-20 · 1 min read

Fisher–Yates shuffle gives every permutation an equal chance

algorithms

Randomly sorting an array with Math.random() looks convenient, but it produces biased results because the sort algorithm wasn't designed for random comparisons.

The Fisher–Yates shuffle avoids this by walking backwards through the array, swapping each element with a randomly chosen element from the unshuffled portion:

function fisherYatesShuffle<T>(array: T[]): T[] {
  const arr = [...array];

  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));

    [arr[i], arr[j]] = [arr[j], arr[i]];
  }

  return arr;
}

Because every position is chosen exactly once from the remaining candidates, every possible permutation is equally likely. It's the standard algorithm for unbiased shuffling and should be preferred over array.sort(() => Math.random() - 0.5) whenever randomness matters.