NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

SOLVED: Day 9: Functions as parameters question

Forums > 100 Days of SwiftUI

In this lesson the way to create a function that accepts other functions as parameters was like this:

func doImportantWork(first: () -> Void, second: () -> Void, third: () -> Void) {
    print("About to start first work")
    print("About to start second work")
    print("About to start third work")

And it's called like this:

doImportantWork {
    print("This is the first work")
} second: {
    print("This is the second work")
} third: {
    print("This is the third work")

Now, in Checkpoint 5 we are supposed (using that knowledge) to use three functions as parameters(filter, map, sort) on an array. I tried calling them in the way shown above but it kept giving me errors. So after checking here the solution was like this:

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

let newLuckyNumbers = luckyNumbers.filter { $0 % 2 == 1 }
    .sorted{ $0 < $1 }
    .map { "\($0) is a lucky number"}

We have to use . after each closure and not just the name of the parameter then a colon. Can someone explain this to me? I hope I made myself clear enough. this to me? I hope i made myself clear enough.


In that example, you aren't using filter, sorted and map as parameters, you are calling those functions with closures as their parameters.

Here are those functions:

func filter(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> [Self.Element]

func sorted(by areInIncreasingOrder: (Self.Element, Self.Element) throws -> Bool) rethrows -> [Self.Element]

func map<T>(_ transform: (Self.Element) throws -> T) rethrows -> [T]

You can see that each one takes a closure expression as a parameter.

So when, for instance, you call .filter { $0 % 2 == 1 }, the { $0 % 2 == 1 } is the closure being passed in.

The reason you see .filter, .sorted and .map with the leading . is because these are three different functions being chained together onto luckyNumbers. First you call filter to get a filtered array from luckyNumbers, then you call sorted on that filtered array to get the array sorted in ascending order, then you call map to convert the filtered and sorted integers into a String. You are essentially feeding the result of one function into the input of another function.

In this way, you can chain multiple operations together without having to create intermediate variables to hold your results. The long way of doing it:

let filteredLuckyNumbers = luckyNumbers.filter { $0 % 2 == 1 }
let sortedLuckyNumbers = filteredLuckyNumbers.sorted { $0 < $1 }
let mappedLuckyNumbers = { "\($0) is a lucky number"}

Can be shortened to:

let newLuckyNumbers = luckyNumbers.filter { $0 % 2 == 1 }
    .sorted{ $0 < $1 }
    .map { "\($0) is a lucky number"}

Both of these things—passing functions as parameters to other functions and chaining functions together—lie at the core of functional programming.


Thanks for the explanation.


Hacking with Swift is sponsored by Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

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.