LAST CHANCE: 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 Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.