UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

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,

1      

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
}

2      

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!

1      

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

1      

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)"?

1      

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.

1      

My personal soltion:

func funzioTest9( para : [Int]?) -> Int? { para?.randomElement() ?? Int.random(in: 1...100)

}

let provino = funzioTest9(para:[] )

print(provino)

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

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.