The logic behind some complex high order functions in Swift

Shashank Mishra
Mac O’Clock
Published in
4 min readJul 1, 2020

High order function can be passed as an argument to other functions. You can play with collections using these functions with a relatively fewer number of codes. I will try to explain complex high order functions in Swift like Reduce, flatMap, compactMap, and compactMapValues, followed by a few interview tips.

Reduce

Reduce function uses the previous iteration result of an array in order to give the final result(of any data type). Let’s take an example of getting summation of elements of an array.

*shorthand is a compact way of writing high order functions

To understand this function first we will start with its declaration —

func reduce<Result>(initialResult: Result, nextPartialResult: (Result, Element) -> Result) -> Result

First Parameter(initialResult: Result) — takes an initial value of type Result, and combine will execute for each element of the array.

Second Parameter(nextPartialResult(Result, Element)): Result is the previous result of combine & Element is the value of an element that is being combined.

The Result is the value (Result) return by the last combine call.

Below is the tabular explanation of each iteration done by reducing function to provide the sum of array elements(above example).

Time complexity can be represented as O(n), it iterates through all the elements of the array.

There are other examples like concatenating numbers of an array into a string, getting the largest value from the array of numbers, etc.

Mapping functions

Mapping functions are used to convert a collection of values into an array of new values using a transform. You can achieve this using map, flatMap(restricted use), compactMap, compactMapValues that transform a collection of values into a collection of other values.

map function returns transformed array with optional. It returns nil values as well.

flatMap has been deprecated from Swift 4.1 except one usage of flattening the nested collection into a single array(link). You can still use this function in the latest swift for this purpose.

compactMap

It has been introduced in Swift 4.1. It can be applied on an array or a nested array. With the help of it, we can discard nil values in the result of the transform applied on array items.

Suppose you want to convert values of an array of string to an array of integers(discarding nil values). By default, this function discards all nil values from the result.

However, you can still get nil values by casting the result of compactMap() to optional data type.

After casting result as [Int?]

Time complexity can be represented as O(m+n), where n is the length of this sequence and m is the length of the result.

compactMapValues

It works like compactMap. The only difference is that it can be used to transform the values of a dictionary.

Time complexity can be represented as O(m+n), where n is the length of this sequence and m is the length of the result.

Tips

  1. flatMap can’t be totally replaced by compactMap. If you want to flatten a nested array you can’t achieve it using compactMap directly. You can use a flatMap function for this(link). This feature is still not deprecated by Apple totally.
  2. You can reduce an array of one type into a completely different type. That means an array of integers can result in an array of string. (power of generics)
  3. compactMap & compactMapValues can be used to get unwrapped values without adding extra checks. It is safe to use these functions if we are dealing with optional transformed values and the result must be a collection of all non-optional values.

Thanks.

--

--