shuffle
Randomly shuffles elements in an array using the Fisher–Yates algorithm. Returns a new shuffled array without mutating the original.
1/**
2 * Randomly shuffles elements in an array using the Fisher–Yates algorithm.
3 * Returns a new shuffled array without mutating the original.
4 *
5 * @param arr - The array to shuffle.
6 * @returns A new array with shuffled elements.
7 */
8export function shuffle<T>(arr: T[]): T[] {
9 const result = [...arr];
10 for (let i = result.length - 1; i > 0; i--) {
11 const j = Math.floor(Math.random() * (i + 1));
12 [result[i], result[j]] = [result[j], result[i]];
13 }
14 return result;
15}
Uses the Fisher–Yates algorithm
Ensures a uniform random distribution, making it more reliable than naive sorting-based shuffles (e.g.
sort(() => Math.random() - 0.5)
).Non-mutating
Creates a shallow copy of the original array before shuffling, preserving data integrity and functional purity.
Efficient in-place logic
Performs in linear time
O(n)
and constant spaceO(1)
aside from the initial array copy, which is optimal for shuffling.Generic and type-safe
Works with arrays of any type due to its generic signature.
Tests | Examples
1test('shuffle returns array of same length and values', () => {
2 const original = [1, 2, 3, 4, 5];
3 const shuffled = shuffle(original);
4
5 expect(shuffled).toHaveLength(original.length);
6 expect(shuffled.sort()).toEqual(original.slice().sort());
7});
8
9test('shuffle does not mutate original array', () => {
10 const original = [1, 2, 3];
11 const copy = [...original];
12 shuffle(original);
13 expect(original).toEqual(copy);
14});
15
16test('shuffle randomizes the order (probabilistic)', () => {
17 const original = [1, 2, 3, 4, 5];
18 const results = new Set();
19
20 for (let i = 0; i < 100; i++) {
21 results.add(shuffle(original).join(','));
22 }
23
24 // Expect more than one unique permutation over many shuffles
25 expect(results.size).toBeGreaterThan(1);
26});
Common Use Cases
Randomizing order in games or quizzes
E.g. shuffling cards, questions, or answer choices to ensure fairness and unpredictability.
UI and animation sequencing
Dynamically varying the order of displayed elements for aesthetic or testing purposes.
Data sampling and experiments
When you need to randomly order items before slicing or analyzing subsets.
Load balancing or A/B testing
Random distribution of tasks or users to reduce bias in scenarios requiring random assignment.