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

SOLVED: Checkpoint 5 - Am I doing this right?

Forums > 100 Days of SwiftUI

So, it took me a couple of days to come up with this solution for Checkpoint 5:

let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49] 

let solve = { (_: [Int]) in
    luckyNumbers.filter { !$0.isMultiple(of: 2) }
    .sorted()
    .map { print("\($0) is a lucky number.") }
}
solve(luckyNumbers)

This prints out:

7 is a lucky number.
15 is a lucky number.
21 is a lucky number.
31 is a lucky number.
33 is a lucky number.
49 is a lucky number.

So technically it works but the code inside the closure looks disorienting and I have a feeling that I'm missing something. Am I even doing this right? Thanks for any tips.

1      

Welcome to Checkpoint 5!

That disoriented feeling you have is the direct result of declarative programming! It can be dizzying!

You created solve to be a function that takes an array of [Int] and returns nothing. Was this your intention?

Another way to complete this checkpoint would be to create a computed property that does the same as your function.

let _ = luckyNumbers
    .filter { !$0.isMultiple(of: 2) }   // filter out even numbers
    .sorted()                           // sort the odd numbers
    .map { print "\($0) is a lucky number." } // map to strings

This solution uses slightly less code, but can't be used a function. Your code get full marks for being swifty, one line of code, and declarative!

Well done.

3      

You created solve to be a function that takes an array of [Int] and returns nothing. Was this your intention?

It was the only way I could wrap my head around the whole thing at this point. :D I also tried to make it return a String but couldn't get it working...

Another way to complete this checkpoint would be to create a computed property that does the same as your function.

I'll have to play around with this technique. Thanks for the example and encouragement!

1      

Oh, and another thing: Let's assume I want to use solve for another array. Now it exclusively filters luckyNumbers. Could I achieve this by changing luckyNumbers.filter to just .filter and then calling solve(someOtherNumbers)?

1      

Let's assume I want to use solve for another array. Could I achieve this by changing luckyNumbers.filter to just .filter ?

Not quite. You did have one bug in your code.

You wrote:

let solve = { (_: [Int]) in  // this requires an array of [Int], but you never use this array in your solution.
    luckyNumbers.filter { !$0.isMultiple(of: 2) } // Here you HARD coded the array you wanted to process
    // you are NOT using the array that you passed into this code. 
    // By using the _ character, you're telling Swift to ignore what is passed in.

Run this in your playground:

solve(luckyNumbers)  
print("======= Another array of ints ========"
solve( [ 9, 99, 199, 999, 42] )

Both will provide the same result! Why? Because you HARD coded the array name into your filter statement. In the second line, your function accepts the array of [ 9, 99, 199, 999, 42], but ignores it.

To analyze different arrays of ints, you'll need to change your function's signature.

let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]
let moreNumbers = [7, 1, 14, 13, 42, 199, 24]

let solve = { (numbers: [Int]) in    // Change your input, name it numbers. Any array of int will be called numbers in your function.
    numbers.filter { !$0.isMultiple(of: 2) } // numbers is now filtered, sorted, mapped.
    .sorted()
    .map { print("\($0) is a lucky number.") }
}
print("Lucky Number ===========")
solve(luckyNumbers)
print("More Numbers ===========")
solve(moreNumbers)

1      

Ah, I see. I don't quite understand _ yet so I'll have to be careful with it. But the hardcoded array was something I actually noticed by myself and that's what led me to wonder the syntax. So maybe I should frame the actual question differently.

Let's say I start with

let solve = { (numbers: [Int]) in

like in your second example.

Whether I then pass in luckyNumbers or someOtherNumbers or moreNumbers etc. when calling solve(numbers: someNumbers), can I still format the code like in your first example, beginning the function chain inside solve with just .filter instead of numbers.filter?

I'll play around with this in Xcode after I've had my coffee. :D

1      

In Playgrounds (you ARE using playgrounds, yes?!) press the option key then hover your mouse over the variable named solve.

Swift will tell you what solve is.

// Option hover tells me that solve is a function that consumes an array of integers.
// It also returns an array of nothing.
let solve: ([Int]) -> [()]
//
// You can call this function by passing in a variable that's an array.
let moreNumbers = [7, 1, 14, 13, 42, 199, 24]
solve(moreNumbers)
// Or you can pass in an array directly.
solve( [ 9, 12, 99, 22, 42, 199] )

1      

Hacking with Swift is sponsored by Fernando Olivares

SPONSORED Fernando's book will guide you in fixing bugs in three real, open-source, downloadable apps from the App Store. Learn applied programming fundamentals by refactoring real code from published apps. Hacking with Swift readers get a $10 discount!

Read the book

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.