Swift
Array
Shuffling
Programming
iOS Development

How do I shuffle an array in Swift?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

In modern Swift, shuffling an array is built into the standard library. Most of the time you should use shuffle() to mutate an array in place or shuffled() to return a new randomized copy. The main thing to understand is when you want mutation, when you want a copy, and why some older "random sort" tricks should be avoided.

Use the Built-In APIs First

Swift already provides the two most useful operations.

Mutate the original array:

swift
1var numbers = [1, 2, 3, 4, 5]
2numbers.shuffle()
3
4print(numbers)

Return a shuffled copy:

swift
1let letters = ["a", "b", "c", "d"]
2let randomized = letters.shuffled()
3
4print(letters)      // original stays the same
5print(randomized)   // shuffled copy

These methods use the standard library’s randomization facilities and are the correct default choice in current Swift.

Know the Difference Between shuffle() and shuffled()

The names are similar, but the behavior is different:

  • 'shuffle() changes the existing array'
  • 'shuffled() returns a new array and leaves the original untouched'

That matters in real code:

swift
1var deck = ["A", "K", "Q", "J"]
2let copy = deck.shuffled()
3
4print(deck)
5print(copy)

If you expected deck to change here, you chose the wrong method.

Deterministic Shuffling for Tests

In application code you normally want true randomness, but tests often need reproducible results. Swift lets you pass a custom RandomNumberGenerator.

swift
1struct SeededGenerator: RandomNumberGenerator {
2    private var state: UInt64
3
4    init(seed: UInt64) {
5        self.state = seed
6    }
7
8    mutating func next() -> UInt64 {
9        state = 2862933555777941757 &* state &+ 3037000493
10        return state
11    }
12}
13
14var generator = SeededGenerator(seed: 1234)
15let values = [1, 2, 3, 4, 5]
16let shuffledValues = values.shuffled(using: &generator)
17
18print(shuffledValues)

That is useful for testing because the same seed produces the same sequence.

If You Need to Support Older Swift

Before the built-in shuffle APIs were available, developers often implemented Fisher-Yates manually. That algorithm is still worth understanding because it is the correct way to shuffle uniformly.

swift
1extension Array {
2    mutating func fisherYatesShuffle() {
3        guard count > 1 else { return }
4
5        for i in stride(from: count - 1, through: 1, by: -1) {
6            let j = Int.random(in: 0...i)
7            if i != j {
8                swapAt(i, j)
9            }
10        }
11    }
12}
13
14var items = [10, 20, 30, 40]
15items.fisherYatesShuffle()
16print(items)

In modern Swift, this is mostly educational or useful only when maintaining older code.

Do Not Shuffle by Sorting with Random Comparisons

A tempting but incorrect shortcut is:

swift
let values = [1, 2, 3, 4, 5]
let wrong = values.sorted { _, _ in Bool.random() }
print(wrong)

This should be avoided because:

  • it does not produce a uniform shuffle
  • the comparator is inconsistent
  • sort algorithms expect ordering rules, not randomness

If you want a true shuffle, use shuffle(), shuffled(), or Fisher-Yates.

Performance Notes

Built-in shuffling is efficient for normal use and runs in linear time relative to the number of elements. That is the right complexity for a real shuffle because each element needs to be considered at least once.

If the array is extremely large and you only need a random sample, shuffling the whole array may do unnecessary work. In that case, consider sampling algorithms instead of a full permutation.

Common Pitfalls

The most common mistake is forgetting that shuffled() returns a new array. If you ignore the returned value, nothing changes.

Another issue is using a custom random generator incorrectly. Methods that accept a generator usually require an inout mutable generator, so remember the &generator syntax.

Developers also sometimes write their own shuffle even though the standard library already provides one. That adds maintenance burden for no gain unless you truly need custom behavior.

Finally, avoid random sorting hacks. They look short, but they are algorithmically wrong.

Summary

  • Use shuffle() to randomize an array in place.
  • Use shuffled() when you want a randomized copy.
  • Pass a custom RandomNumberGenerator when you need deterministic test behavior.
  • Fisher-Yates is the correct manual algorithm for older codebases.
  • Do not try to shuffle by sorting with a random comparator.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.