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!