Higher Order Functions in Swift – Filter, Map, Reduce

In this post we will discuss three important higher order functions – Filter, Map, Reduce used in functional language and their use in Swift. Swift standard library contains these three functions as an extension to Array(List) type and as well as separate functions. Lets see what we can do with these functions.

Map

Map is a function that takes a list and an unary function, applies this function to each element of the list and outputs a modified list.

Example 1

Map each value in array to twice its value. The new values are contained in a new array mappedArray.

let array: [Int] = [1,2,3]

let mappedArray: [Int] = map(array, {$0 * 2})

Filter

Filter function takes a unary function returning a Boolean (predicate) and some list of values, producing a new list containing those values from the original list for which the predicate returns true.

Example 2

Filter out even numbers from a list.

let array: [Int] = Array(1…10)

let filteredArray: [Int] = filter(array, {return (($0 % 2) == 0)})

result:

array = [1,2,3,4,5,6,7,8,9,10], filteredArray = [2,4,6,8,10]

Reduce

Reduce (alist, initialValue, combineFunc) function combines the values to produce a single value by applying combineFunc function on the list alist recursively.

If the list is [l1, l2, l3, l4] and the initial value is l0, after the first step the list would look like:

[combineFunc(l0, l1), l2, l3, l4],

and after the next step it would look like:

[combineFunc(combineFunc(l0, l1), l2), l3, l4] and so on.

Example 3 – Sum of numbers in a list

let array: [Int] = Array(1…10)

let result: Int = reduce(array, 0, {$0 + $1})

Example 4 – Maximum of numbers in a list.

let array: [Int] = Array(1…10)

let result: Int = reduce(array, 0, {if $0 > $1 {return $0;} else {return $1}})

Example 5 – Finding the line in a list containg maximum number of vowels.

let lines: [String] = [

“Donec condimentum nibh vitae accumsan vehicula.”,

“Ut ullamcorper libero id consectetur sodales.”,

“Fusce sodales ipsum ultricies risus pulvinar convallis.”,

“Donec vitae arcu id nisi congue tincidunt.”]

Let`s first calculate vowel count for each line and store (vowelCount, line) tuples in an array.

let vowelCountsLines: [(Int, String)] = map(lines,

{  var vowelCount: Int = 0

for character in $0 {

if character == “a” || character == “e” || character == “i” || character == “o” || character == “u” {      vowelCount += 1    }  }

return (vowelCount, $0)  })

Now find the line using reduce

let (maxVowel, maxLine): (Int, String) = reduce(vowelCountsLines, (0, “”), {if $0.0 > $1.0 {return $0;} else {return $1}})

Author: Sujal Ghosh