Table of contents
1.
Introduction
2.
Map
3.
CompactMap
4.
FlatMap
5.
Filter
6.
Reduce
7.
ForEach
8.
Contains
9.
FAQs
9.1.
What are higher-order functions in swift?
9.2.
What are $0 and $1 in swift?
9.3.
What is the difference between a callback and a higher-order function?
9.4.
Why do higher-order procedures lead to better programming results?
10.
Conclusion
Last Updated: Mar 27, 2024

Swift Higher Order Function

Author soham Medewar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In real-world programming, higher-order functions are a terrific tool that we can only benefit from; we can avoid adding functionality that is already present in Swift, and we can achieve more with less, which means we can get the same outcomes with fewer lines of code. Higher-order functions are typically used in collections (arrays, dictionaries, and sets), and their purpose, as you will learn in the following sections, is to perform various operations on the included components. Despite their name, functions are accessed as methods through the dot syntax via the collection object that they will be used with.

In this article, we will be discussing the following functions:

  • Map
  • CompactMap
  • FlatMap
  • Filter
  • Reduce
  • ForEach
  • Contains

Map

Let's begin with a map, the first and possibly most well-known higher-order function. This function operates on all of the elements in a collection and returns a new collection containing the results of the operation on the original components. It sounds fantastic, but how does it actually work?

Let us take an example; suppose you have an array (number from 1 two 10). Now you have to multiply each number by 5 in the array without using any for loop. This can be done in simple ways by using a map.

Code

// array
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// printing array before using map operation
print("Before \(x)")

// using map operation (multiplying each value by 5)
x = x.map({ $0*5 })

// printing array after using map operation
print("After \(x)")

Output

Before [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]

CompactMap

The compactMap method is quite similar to the map, with one major difference: the returned array does not contain any nil values. To demonstrate, consider the following example, in which the array contains integer numbers with nil values:

//  array
var x = [1, 2, nil, 4, 5, 6, nil, 8, 9, nil]

Now, we can multiply every element of the array expect the nil values by using simple map using the below code snippet.

Code

// using map operation (multiply every element of array by 2 expect null value)
x = x.map({
    $0 != nil ? $0! * 2 : nil
})

// printing array before using map operation
print("After \(x)")

Output

After [Optional(2), Optional(4), nil, Optional(8), Optional(10), Optional(12), nil, Optional(16), Optional(18), nil]

However, having an array with optional and nil elements, as seen in the preceding result, is not always ideal. In that instance, the compactMap method comes in handy. When used in the x array(having nil elements), the resulting array will include only non-nil items and will be of type [Int].

The following code will show the implementation of the compactMap function.

Code

// using compactMap operation (multiply every element of array by 2 expect null value)
let v = x.compactMap({$0 != nil ? $0! * 2 : nil})

// printing array before using map operation
print("After \(v)")

Output

After [2, 4, 8, 10, 12, 16, 18]

FlatMap

The flatMap is handy when there are collections within collections that need to be merged into a single collection. Examine the array below, which contains other arrays as elements. Assume that each inner array holds a student's grades from three separate courses:

// array x
let x = [[1, 2, 3], [9, 8, 7], [19, 20, 21], [13, 14, 15]]

Now, we will use the flatMap function to combine all the subarrays into a single array.

Code

// printing array x
print("Before \(x)")

// combining all the subarrays
let combined_x = x.flatMap { (array) -> [Int] in
    return array
}

// printing the final combined array
print("After \(combined_x)")

The above code can also be written in the following format:

// combining all the subarrays
let combined_x = x.flatMap { $0 }

Output

Before [[1, 2, 3], [9, 8, 7], [19, 20, 21], [13, 14, 15]]
After [1, 2, 3, 9, 8, 7, 19, 20, 21, 13, 14, 15]

Filter

The filter higher-order function is one of the most useful and maybe a terrific tool when employed. Its objective, as the name implies, is to filter the components of a collection based on a condition and create a new one having only those elements that satisfy the criterion.

Let us take an example; suppose you have an array (number from 1 two 10). Now you have to remove all the odd numbers from the array without writing a for loop. This can be done using a filter.

Code

//  array
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// printing array before using map operation
print("before \(x)")

// using filter operation (sorting out even numbers)
x = x.filter({
    return $0 % 2 == 0   
})

// printing array after using map operation
print("after \(x)")

Output

Before [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
After [2, 4, 6, 8, 10]

Reduce

The reduce higher-order function's goal is to generate a single value from the values of all elements in a collection. To see what this implies, consider calculating the sum of the numbers in the following array without using a for loop:

//  array
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

We will be using reduce function to calculate the sum of all the numbers from the array.

Code

// using reduce operation (sum of all numbers in array)
let result = x.reduce(0, {sum, value in
    sum + value
})

// printing result
print("Sum of all the numbers in the array: \(result)")

Output

Sum of all the numbers in the array: 55

The above code can also be written in a simpler form as shown below.

let result = x.reduce(0, { $0 + $1 })

Or else,

let result = x.reduce(0, +)

All the above codes will produce the same output.

ForEach

Developers are well-versed in writing for-in loops to iterate through the components of a collection. For example, the following code illustrates how to iterate through the elements of the numbers array and report if each number is even or odd:

Code

//  array
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// for loop using forEach function
x.forEach{ $0.isMultiple(of: 2) ? print("\($0) is even") : print("\($0) is odd")}

Output

1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even

Contains

The contains function is used in collections to determine whether or not there are elements that meet a specific requirement and returns a boolean value. Assume our purpose is to determine whether the x array includes values less than 5. A loop search could be used as a solution but contains a function that provides an easy way to search through the array.

Code

//  array
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// checking whether the array has numbers less than 5
let hasNumbersLessThan5 = x.contains { $0 < 5 }
if(hasNumbersLessThan5){
    print("Yes, array has some elements less than 5")
}else{
    print("No, array don't have any element less than 5")
}

// checking whether the array has numbers greater than 10
let hasNumbersGreaterThan10 = x.contains { $0 > 10 }
if(hasNumbersGreaterThan10){
    print("Yes, array has some elements greater than 10")
}else{
    print("No, array don't have any element greater than 10")
}

Output

Yes, array has some elements less than 5
No, array don't have any element greater than 10

FAQs

What are higher-order functions in swift?

A higher-order function is one that accepts one or more functions as inputs and returns another function as a result.

What are $0 and $1 in swift?

$0 and $1 are the closure's first and second Shorthand Argument Names (SAN) or implicit parameter names, respectively. Swift generates the abbreviated argument names automatically. The first argument is referenced by $0, the second argument by $1, the third by $2, and so on.

What is the difference between a callback and a higher-order function?

A higher-order function is one that accepts another function as an input and/or returns another function to its callers. A callback function is one that is supplied to another function with the expectation that it will be called by the other function.

Why do higher-order procedures lead to better programming results?

Higher-order functions enable flexibility and generality, making your code both more powerful (you may use the same function for multiple use-cases) and compact when a programming language correctly supports functional programming notions.

Conclusion

In this article, we have discussed some higher-order functions like map, reduce, filter, etc., that makes code easy to understand and compact and also make the programming results better.
Check out this problem - Maximum Product Subarray

Want to learn more about web development or android development? Here is an amazing course for both by coding ninjas.

Happy Learning!

Live masterclass