Higher order functions in Swift: Filter, Map, Reduce, flatmap, compactMap

Ever since I learned about functions and closures in detail, I wanted to know more about the advantages and usages of these in programming. I read about higher order functions that can be used on collection types and this is what I understood.

I don’t know who that is over there at the top.

Pass function to another function:

higher order functions in swift

Return function from another function:

You should understand what a closure is before going through the following. Read my article on closures

Map

Use map to loop over a collection and apply the same operation to each element in the collection. The map function returns an array containing the results of applying a mapping or transform function to each item.

Map on array:

Suppose we have an array of integers:

let arrayOfInt = [2,3,4,5,4,7,2]
var newArr: [Int] = []for value in arrayOfInt { newArr.append(value*10) }print(newArr) // prints [20, 30, 40, 50, 40, 70, 20]
maps on int array
let newArrUsingMap = arrayOfInt.map { $0 * 10 }
simplifying the map closure syntax

Map on Dictionary:

Consider a dictionary with book names as key and the amount of each book as the value.

let bookAmount = [“harrypotter”:100.0, “junglebook”:100.0]
map on dictionary
map on dictionary return values

Map on set:

What if you want to know the index of the collection while applying map to it??

Answer is simple. You will have to enumerate it before mapping.

let numbers = [1, 2, 4, 5]let indexAndNum = numbers.enumerated().map { (index,element) inreturn "\(index):\(element)"
}
print(indexAndNum) // [“0:1”, “1:2”, “2:4”, “3:5”]

Filter

Filter on array

Consider the following code to filter even numbers from an array of integers.

filter using for-in loop
filter an int array
Simplified filter closure on Int array

Filter on dictionary

Consider a dictionary with book names as key and the amount of each book as the value.

let bookAmount = [“harrypotter”:100.0, “junglebook”:1000.0]
filter autocomplete on dictionary
let filteredArrayOnDict = bookAmount.filter { $1 > 100}

Filter on set

filter on set

Reduce

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
  • One is an initial value which is used to store the initial value or the value or result returned by the closure from each iteration.
  • The other one is a closure which takes two arguments, one is the initial value or the result from the previous execution of the closure and the other one is the next item in the collection.

Reduce on arrays

Let’s understand this with an example:

reduce method on arrays
  1. Initial value is 0, x is 0, y is 1 → returns x+y . So, initial value or Result becomes 1.
  2. Initial value or Result is 1, x is 1, y is 2 → returns x+y . So, initial value or Result becomes 3 .
  3. Initial value or Result is 3, x is 3, y is 3→ returns x+y . So, initial value or Result becomes 6.
  4. Initial value or Result is 6, x is 6, y is 4→ returns x+y . So, initial value or Result becomes 10
let reducedNumberSum = numbers.reduce(0) { $0 + $1 }print(reducedNumberSum) // prints 10
reducing on int array
let reducedNumberSum = numbers.reduce(0,+) // returns 10
let reducedNumberSum = numbers.reduce(0) { $0 * $1 }
// reducedNumberSum is 0...
let reducedNumberSum = numbers.reduce(0,*)
let codes = ["abc","def","ghi"]let text = codes.reduce("") { $0 + $1} //the result is "abcdefghi"orlet text = codes.reduce("",+) //the result is "abcdefghi"

Reduce on dictionary

Let’s reduce the bookAmount Dictionary:

let bookAmount = [“harrypotter”:100.0, “junglebook”:1000.0]
reducing dictionary
  1. An initial or result value of the type that should be reduced to.
  2. A tuple of current key-value pair.
let reducedBookNamesOnDict = bookAmount.reduce(“Books are “) { $0 + $1.key + “” } //or $0 + $1.0 + “”

Reduce on set

The reduce on set works the same way as in arrays.

Flatmap

Flatmap is used to flatten a collection of collections . But before flattening the collection, we can apply map to each elements.

Read it like : map + (Flat the collection)
(fig — 1) Read the above definition and have a look at this code.
(fig — 2)… and this (string is a collection from swift 4).
[“abc”,”def”,”ghi”].map { $0.uppercased() }
output: [“ABC”, “DEF”, “GHI”]
output: ["A", "B", "C", "D", "E", "F", "G", "H", "I"]
Finally, this is what flatMap does to a string

Tip:

In swift 3, flatmap was also used for removing nil values from a collection. This is deprecated now and the complier will throw a warning when used.

I think, now it is clear what a flatMap does.

Flatmap on array

flatmap of array of array of int

Flatmap on array of dictionaries

It returns an array of tuples after flatmapping. We have to convert it to an array:

flatmap an array of dictionaries

Flatmap on set

flatmap on set

Advantages of flatmap:

Let’s dig into the advantages of flatmap:

Removing optionals:

flatmap to remove optionals.

Flatmap by filtering or mapping

We can apply flatmap on collection of collections. ie; an array of arrays will be flattened to a single array. So, the flatmap closure takes a single collection of argument, do something with this collection and /or return the collection. Here , before returning the collection, we can apply filter or map or even reduce.

filtering while flatmap
let onlyEven = collections.flatMap { $0.filter { $0 % 2 == 0 } }

Chaining : (map + filter + reduce)

We can chain multiple higher order functions one by one.

You can read my article on chaining methods to understand its working.

The working principle behind the chaining is simple. The map and filter methods act on a collection and returns another collection . And now, we can again apply another higher order function on this collection. It’s that simple.

add the squares of all the even numbers from an array of arrays.

CompactMap

Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.

compactmap on dictionary

Tip:

Conclusion

Well, thats it!! You mastered Higher order functions!!

  • It improves your swift skills.
  • Enhances readability of code.
  • More functional programming.

If you enjoyed reading this post, please share and give some clapps so others can find it 👏👏👏👏👏 !!!!

You can follow me on Medium for fresh articles. Also, connect with me on LinkedIn and Twitter.

--

--

iOS and tvOS developer, dreamer, photographer 🤨

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store