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

SOLVED: Day 14: checkpoint 9

Forums > 100 Days of SwiftUI

Hi,

The challenge is to:

  • write a function that accepts an optional array of intergers, and returns one of those intergers randomly
  • if the array is missing or empty, return a new random number in the range 1 through 100
  • write the function is one line of code

Without reading the third instruction, I tried to use what I understood about Guard Let to solve this problem. Once I saw the 3rd instruction and listened to the hints, I solved it. However I realise that I must mis-understand how guard let works, because my code doesn't compile when I think it ought to.

func randomSelector3(of array: [Int]?) -> Int {
    guard let array = array else {
        return Int.random(in: 1...100)
    }

    return array.randomElement()
}

with this function I get the error next to return array.randomElement() saying : Value of optional type 'Int?' must be unwrapped to a value of type 'Int'

My understanding is that once the guard let method has been passed, the variable array is no longer an Optional. I have already unwrapped the value by virtue of using the guard let at the top of the function.

Can someone please explain why the error is suggesting that array hasn't been unwrapped, even when it's passed the guard let mechanism?

Thanks,

   

Think you getting confused with your optional.

Your parameter array is optional and the guard does unwrap that optional, however randomElement() will also give you an optional Int as the complier does not know if there will be any items in the array. So you need to handle it. You can force unwrap it with! as You know that there will some items in the array or better is to nil coalescing (even though the default will not be called).

func randomSelector3(of array: [Int]?) -> Int {
    guard let array = array else {
        return Int.random(in: 1...100)
    }
    // return array.randomElement()! <- One option
    return array.randomElement() ?? 0
}

1      

Thanks very much. I understand now. I thought it was asking for that because I hadn't unwrapped it with the guard. But instead its just the function I'm calling in and of itself returns an optional, regardless of the guard let above. I get it. Thanks!

   

You can option click on .randomElement() in Xcode to display a definition of it.

   

Optionals are still hard to handle, but it gets clearer from day to day...

func randomChoice(of myIntArray: [Int]?) -> Int {
    return myIntArray?.randomElement() ?? Int.random(in: 1...100)
}

print (randomChoice(of: []))
print (randomChoice(of: [1,2,3,4]))

// Why that? 
print (randomChoice(of: ))
// prints out "(Function)"

I don't understand, why it prints (Function), when I don't give an array into the function? The array is optional. Doesn't that mean, if there is no array at all, it should just print out an "Int.random(in: 1...100)"?

   

print (randomChoice(of: ))

In this code you are passing a reference to a function, not calling the function. You still need to pass something in the parameter, even if the array doesn't exist.

print(randomChoice(of: nil))

This is how you would call the function without supplying an array.

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

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.