WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: Question: how come randomElement() could come back with no value ?

Forums > 100 Days of SwiftUI

Hello ,

When Paul demonstrating nil-coalescing, he used the codes below:

let names = ["Arya", "Bran", "Robb", "Sansa"]
let chosen = names.randomElement()?.uppercased()
print("Next in line: \(chosen ?? "No one")")

I don't understand how come .randomElement() may end up with no value coming back ?

I mean, it is an Array, and randomElement 's mission is picking one item from it, and it couldn't fail, right ?

What's the point of using Optionals or Nilcoalescing in this case ?

Thank you in advance



The array could be empty in which case .randomElement() would return nil. In your example, you set all the values in the array so you know it's not empty, so .randomElement() would always return something if you forced it with !.

Since Swift plays it safe and makes .randomElement() return an optional, you have to treat it as an optional.

However, in something like Project 7, the iExpense project, we start the project with no data. We're using a class that's an array of data created by looking for data in UserDefaults that hasn't been created yet, so we assign the class an empty array. Trying to use .randomElement() on it by forcing it with ! would crash the program. The array gets populated once we start adding data.

Here's an example to try in a playground:

let myArray = [String]()
var randomItem = myArray.randomElement()
// Prints - nil

randomItem = myArray.randomElement()!
// Crashes the playground
//__lldb_expr_5/Main.xcplaygroundpage:7: Fatal error: Unexpectedly found nil while unwrapping an Optional value


Vince correctly replies:

The array could be empty in which case .randomElement() would return nil.

Most of these characters survived. So as Vince said, randomElement() will always return a character.

let names = ["Arya", "Bran", "Robb", "Sansa"] // most survive

But if you started with these characters....

// Paste into Playgrounds.
var characters = ["Cersei", "Sandor", "Joffrey", "Shey", "Little Finger", "Hodor", "Tommen"]

// Roll the dice!
var whoDiesNext = characters.randomElement()

// Create a new array of characters, less one unlucky soul.
characters = characters.filter{ $0 != whoDiesNext }

// Next episode's characters.
whoDiesNext = characters.randomElement() // keep going!

At some point in your program, whoDiesNext will fail. You won't have a character to kill off!
This is why randomElement() returns an optional.


Thank you both @@vtabmow and @Obelix.

Yes I udnerstood the notion of the Array being empty at the begining of running the app, so I thought yes it was empty but the accessing won't happen until some user writes data into it anyway, so that emptiness won't crash the app at the moment that the app was opened.

However thanks to Obelix that now I could see it is also possible that an Array being empty during/after the app has been run, so it is pre-emptive to have the data being optional.

Sorry about delayed reacting. Was having a busy few days.

Have a nice weekend folks !



Hacking with Swift is sponsored by Emerge

SPONSORED Why are Swift reference types bad for app startup time, and what’s the performance cost of protocol conformances? That’s just a couple of the topics you can learn about on the Emerge blog — written by the app performance experts behind Emerge’s advanced app optimization and monitoring tools, based on their experience of working at companies like Apple, Airbnb, Snap, and Spotify.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.