- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
What are the higher-order functions in Swift?
Throughout this tutorial, you will learn about the higher-order functions available in Swift. You will find out what they are used for and how to use them.
What are they?
A higher-order function is a function that takes one or more functions as arguments or returns a function as its result. Below are the higher-order functions provided by the Swift language −
forEach()
map()
compactMap()
flatMap()
filter()
reduce()
sort()
sorted()
All the higher-order functions are based on closure but don't worry you don't need to be a master of closure. They are easy to use and also reduce the size of the code in the project.
Why should you use them?
You can indeed do the same things without using higher-order functions. By utilizing higher-order functions in your code, however, you can avoid implementing functions that are already available in the Swift language in a very optimized manner.
Here we will look at all the functions with examples. Each will be discussed in detail with a practical example.
forEach()
It will iterate through all the elements in a collection (eg array) and not return anything. Remember that you cannot use continue and break inside the forEach function to exit the currently executing statement.
The ForEach function is similar to the for-in loop with a difference i.e. you cannot use continue and break statements in the forEach function.
Example
let numbersInWord = ["One", "Two", "Three", "Four", "Five", "Six"] numbersInWord.forEach { element in print(element) }
Output
One Two Three Four Five Six
Explanation
In the above example, you can see the forEach function iterating over all the elements. When you want an iteration over all the elements without breaking the execution flow, forEach() is best to use.
map()
The map function works by performing an operation on all the elements of a collection and returning a new collection with the results of that operation.
This function is designed to transform an object from one type to another type (as well as the same type).
Example 1
let numbers = [1, 2, 3, 4, 5, 6, 7] let numbersInString = numbers.map { number in String(number) } print("numbersInString: \(numbersInString)")
Output
numbersInString: ["1", "2", "3", "4", "5", "6", "7"]
Explanation
In the above example, you are converting each Int to a String using the map function. You can see how easy it is to map all the input elements.
Anyway, we can reduce this expression by using the shorthand argument $0, which refers to any element of the array. Below is an example −
Example 2
let lowercasedNumbers = ["one", "two", "three", "four"] let uppercasedNumbers = lowercasedNumbers.map({ $0.uppercased() }) print("uppercasedNumbers: \(uppercasedNumbers)")
Output
uppercasedNumbers: ["ONE", "TWO", "THREE", "FOUR"]
Explanation
In the above example, we used $0 which represents the shorthand argument name to access the element inside the closure block. Here, $0 will give you the current argument's value.
compactMap()
Iterating through the elements in an array, compactMap() returns an updated array only containing elements that satisfy the condition stated within its body. The array will be updated without any elements that result in a nil value.
As a result, compactMap loops through all the elements in the array and returns non-nil values.
Example
let numbersInString = ["1", "x2", "3", "4", nil, "five5"] let validNumbers = numbersInString.compactMap { stringValue in Int(stringValue ?? "") } print("validNumbers: \(validNumbers)")
Output
validNumbers: [1, 3, 4]
Explanation
In the above example, the resulting array will not contain any nil values. The resultant array is guaranteed to have non-nil values.
flatMap()
The flatMap function allows us to transform a set of arrays into a single set that contains all of the elements.
Example
Here is an array that contains other arrays as elements. Suppose each inner array contains a student's marks for three different courses −
let marks = [[3, 4, 5], [2, 5, 3], [1, 2, 2], [5, 5, 4], [3, 5, 3]]
Now we have to combine all the marks and get the result into a single array.
We can perform a for-in loop and append all elements of each array to a result array. But why would you need to do it manually if you have a flatMap function provided by the Swift language? It takes less effort and is more optimized.
let marks = [[3, 4, 5], [2, 5, 3], [1, 2, 2], [5, 5, 4], [3, 5, 3]] let allMarks = marks.flatMap { marksArray -> [Int] in marksArray } print("allMarks: \(allMarks)")
Output
allMarks: [3, 4, 5, 2, 5, 3, 1, 2, 2, 5, 5, 4, 3, 5, 3]
filter()
The filter() will iterate through all elements in an array and will return an updated array only with the elements which satisfy the condition written inside the body of the filter.
In Swift, it is always an essential function. While you write code, many times you need to filter out collections to produce a filtered collection based on a condition.
The return type of the closure is a Bool value; items in the resulting array are those that satisfy the condition inside the body;
Example
let numbers = [-12, 23, -1, 56, 9, -2, 0, 14, 8] let positives = numbers.filter { number in number > 0 } print("positives: \(positives)")
Output
positives: [23, 56, 9, 14, 8]
reduce()
The reduce function will iterate through all elements in an array and return an object with the combined value of all elements.
Example
let numbers = [1, 5, 2, 10, 6] let sum = numbers.reduce(0) { (result, number) -> Int in result + number } print("sum:", sum)
Output
sum: 24
Explanation
Above, the first argument is the result of the previous calculation that will be added to the number value. You can understand the logic behind the reduce function as follows −
// 1st iteration: result = 0, number = 1, Return 1 // 2nd iteration: result = 1, number = 5, Return 6 // 3rd iteration: result = 6, number = 2, Return 8 // 4th iteration: result = 8, number = 10, Return 18 // 5th iteration: result = 18, number = 6, Return 24
sort() & sorted()
The sort function will sort all elements according to the condition written inside the body of the closure.
The sorted function will sort all elements according to the condition written inside the body of the closure and return a new sorted array.
sort()
Example
var numbers = [1, 5, 2, 10, 6] numbers.sort() print("Sorted numbers: \(numbers)")
Output
Sorted numbers: [1, 2, 5, 6, 10]
Explanation
In the above example, we initialised a variable that contains unsorted numbers. We have to sort them without using any other variable or constant. In that case, we use the sort() function which sorting elements within the same variable.
Note here, we can use sort() on a variable, not on a constant because sort() uses the same variable to sort the elements.
sorted()
Example
let numbers = [1, 5, 2, 10, 6] let sortedArray = numbers.sorted() print("sortedArray:", sortedArray)
Output
sortedArray: [1, 2, 5, 6, 10]
Explanation
This function sorts the elements and returns a new sorted array.
Conclusion
This article demonstrated how to use higher-order functions in Swift. You are now confident enough to use them in your code. Make sure you learn more about them and do some practical examples.