Higher Order Functions in Swift

Stefano Frosoni
If let swift = Programming!

--

Higher order functions are simply functions that can either accept functions or closures as arguments, or return a function/closure.

I will briefly introduce some very useful higher order functions you can use on collection types using some examples. Those function are Map, Filter, Reduce, Sort, CompactMap, Chaining, Contains, Partition.

But there are a few more to play with in fact Swift 4.2 introduce also new collection higher order functions as allSatisfy, firstIndex, lastIndex and removeAll.

So let’s open a Playground and play a bit with the code.

Map

Map can be used to loop over a collection and apply the same operation to each element in the collection.

Let’s assume we need to multiply each item by 3 in an array called numberArray

In these examples above map accepted a closure as an argument and returned the result in the new array that contains [3, 6, 15, 24, 27, 9].

Just another example using an array of strings:

In this case the result is: [“stefano”, “brian”, “john”, “kate”, “luca”, “zoe”].

CompactMap

CompactMap is the same as the Map function but with optional handling capability. Use this method to receive an array of non optional values when your transformation produces an optional value.

If we used map(_:) on possibleNumbers the result would be [1, 2, nil, nil, 5] but beacsue we are using compactMap(_:) the result is [1, 2, 5].

Filter

Filter can be used to loop over a collection and return a new collection containing only those elements that match the given predicate.

In those examples we wanted a new array that contains only even numbers and an array that contains only words that start with ” S” and the resulting arrays are[2, 8] and [“Stefano”].

Reduce

Reduce is used to combine all items in a collection to create a single new value. The reduce method takes two values, an initial value (initialResult) and a combine closure (nextPartialResult). It need the initial result to tell where to start, and the method then operates on that result based on the logic in the closure. The result is the final accumulated value of any type.

Here numberSum is equal to 10 and following steps occur:

  1. The nextPartialResult closure is called with initialResult (0 in this case) and the first element of numbersArray, returning the sum: 1.
  2. The closure is called again repeatedly with the previous call’s return value and each element of the sequence.
  3. When the sequence is exhausted, the last value returned from the closure is returned to the caller.

Sort (Sorted)

With sort() You can sort any mutable collection of elements that conform to the Comparable protocol by calling this method. In this case Elements are sorted in ascending order. The sorting algorithm is not stable.

Here’s an example of sorting a list of names. Strings in Swift conform to the comparable protocol, so the names are sorted in ascending order:

The result is: [“Brian”, “John”, “Kate”, “Luca”, “Stefano”, “Zoe”].

To sort the elements of the collection in descending order, pass the greater-than operator > to the sort(by:) method.

In this case the result is: [“Zoe”, “Stefano”, “Luca”, “Kate”, “John”, “Brian”].

Let’s see another example of sort()

In this case the result is: [“Zoe”, “John”, “Kate”, “Luca”, “Brian”, “Stefano”].

While Sort() sorts the collection in place, Sorted() return a sorted array of the sequence’s elements.

Chaining

Chaining is the ability to combine all those Higher Order Functions you’ve just learned in one line of code!

To make an example let’s filter out names that don’t start with “S”, make them uppercase and then sort them.

Result: [“SEAN”, “STEFANO”]

Contains

Returns a Boolean value indicating whether the sequence contains an element that satisfies the given predicate.

Partition

This method reorders the elements of the collection such that all the elements that match the given predicate are after all the elements that don’t match.

After partitioning a collection, there is a pivot index P where no element before p satisfies the belongsInSecondPartition predicate and every element at or after p satisfies belongsInSecondPartition. This method, rather than returning a new array, actually changes the array itself.

Swift 4.2 introduce new collection higher order functions.

allSatisfy
Previosly we saw the contains method that return a bool based on whether at least one element in a collection satisfies a condition. The new allSatisfy method instead returns a bool based on whether all elements satisfy a condition.

firstIndex and lastIndex

We now have firstIndex(where:) and firstIndex(of:) that return the first index where the specified value appears in the collection. We have also lastIndex(of:) and lastIndex(where:) that returns the last index in which an element of the collection satisfies the given predicate.

removeAll

Now we have a new method removeAll(where:) that removes all the elements that satisfy the given predicate.

I think that those Higher Order Functions are very useful and powerful and help us to write more elegantly and maintainable code.

Thanks for your time! I hope you find this article useful.

Get in touch on Twitter: stefanofrosoni

--

--