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

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")
    first()
    print("About to start second work")
    second()
    print("About to start third work")
    third()
    print("Done!")
}

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 = sortedLuckyNumbers.map { "\($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.

   

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.