How to shuffle an array in Swift

By

Learn how to shuffle an array in Swift two ways: the shuffle() method that mutates the array in place, and shuffled() that returns a new shuffled array.

~~~

This tutorial belongs to the Swift series

To shuffle an array in Swift you have two options: shuffle() reorders the array in place, and shuffled() returns a new array with the items in random order.

Which one you pick depends on whether you want to keep the original order around.

Shuffle in place with shuffle()

Suppose you have an array of cards in Swift, like this:

var cards = [3, 7, 1, 9, 4]

and you want to shuffle it, so that you get its items in random order.

One way is mutating the original array, and it’s using the shuffle() method that shuffles the items in the array:

cards.shuffle()
//cards is now [9, 3, 4, 1, 7] for example

The original order is gone. Every call reorders the array again.

Note that I used var, because an array is a struct. If I declare it with let then it’s immutable, and calling shuffle() gives a compile error:

cannot use mutating member on immutable value: ‘cards’ is a ‘let’ constant

This is the most common mistake with shuffle(). The fix is to declare the array with var, or to use shuffled() instead.

Get a new shuffled array with shuffled()

Another way is not mutating the original array, but returning a new one, and it’s using the shuffled() method:

let cards = [3, 7, 1, 9, 4]
let shuffledCards = cards.shuffled()
//shuffledCards is [1, 9, 3, 7, 4] for example
//cards is still [3, 7, 1, 9, 4]

Note that here I am safe to use let to declare my variables because shuffled() does not mutate the original array.

shuffled() also works on things that are not arrays. It’s defined on sequences, so you can call it on a range, and you get back an array:

let order = (1...5).shuffled()
//[4, 1, 5, 2, 3] for example

This is a nice way to generate the numbers from 1 to 5 in random order, for example to decide the turn order in a game.

Ranges don’t support shuffle(), the in-place version, because you can’t reorder a range. Only mutable collections like arrays do.

Which one should you use?

My advice is to prefer shuffled(). It lets you use let, it keeps the original data intact, and it works on more types.

Reach for shuffle() when you genuinely want to reorder an existing array and you don’t care about the previous order, like reshuffling a deck between rounds.

Tagged: Swift · All topics
~~~

Related posts about swift: