Treehouse Intermediate Course - Part 12 (Closures 3)

OK, so a change of plans of where I was yesterday. No matter - an entry before bed instead! Just enough to keep things ticking over. I'm then in Liverpool from Wednesday until Friday. Depending on my use of wifi/hotspot on the journey, I may be able to add in something during the journey there and/or back. Right, enough prelude and let's get going. A quick session!

Start Time - 21:33

Map

Standard Library Functions - certain aspects on Swift are already built in.

So without the use of a closure - how to transform an array of ints so that they are doubled:

let values = [1, 2, 3, 4, 5]

var newArray = Array<Int>()

for number in values {
    newArray.append(number * 2)

}

This is the alternative. 


let doubledArray = values.map { $0 * 2

So interesting tech speak here. The first is the imperative approach - showing line by line instruction. The declarative - the closure one - shows the end result without all the bits/step by step guide of how to get there. OK cool!

So a bit complicated but I'm just about hanging on!

extension Array {
    func customMap<T>(_ transform: (Element) -> T) -> [T] {
        var result = [T]()
        for x in self {
            result.append(transform(x))
        }
        return result
    }
    
}

Let's break this down. The customMap function is essentially the same as the map one. It means that you need to pass in argument which takes an element and returns the generic type. Then that will return an array of that generic type. So it will work for ANY type. The for loop means that the element in the array will then get changed. Still a bit vague at the moment!

let integerValues = ["1", "2", "3", "4", "5"]

integerValues.customMap { Int($0)}

Wow that's it! So it accepts a string, then tries to convert it to an integer. The int function has a failable in it. The return type is technically OPTIONAL int. 

Yes! Without Pasan's help - 

numbers.customMap { String($0) }

To be fair, that was very very obvious to do. 

All of Pasan's code for this next example - 

struct Formatter {
    static let formatter = DateFormatter()
    static func date(from string: String) -> Date? {
        formatter.dateFormat = "d MMM yyyy"
        return formatter.date(from: string)
    }
}
let dateStrings = ["10 Oct 1988", "11 Jan 1947", "28 Mar 2002"]

dateStrings.customMap { Formatter.date(from: $0)}

I'm getting used to TRAILING CLOSURES!

Map combines the power of generics and closures to transform an array. It is not necessarily better than the for loops. It's more about going from one type to another. Or ints to ints but transforming. 

For loops are good for side effects.

 

let numbers = [1,2,3,4,5]

let numberStrings = numbers.map { String($0) }


Very, very easy!

Finish Time - 21:59 (26 minutes)

A short entry but great for ticking over. Really useful to learn a key new skill here with 'map' and get an understanding of how the closures come in AND what is happening 'under the hood'. Like I said, hopefully I'll be able to do some more on the coach to Liverpool. Worst case scenario, next time will be Friday!

Comments

Popular posts from this blog

*Xcode Project Entry 2* F1 Quiz - part 1

Angela Yu Course Part 10 (up to lesson 112)

Angela Yu Xcode 12 Course - Part 7 (lectures 74 to 79)