Higher Order Functions(Swift):
Higher order functions are concept behind functional programming in swift.
It’s sounds like something very complex but on contrary it’s very simple.
Definition: Functions that can either accept functions or closures as arguments or return a function/closures are called as higher order functions.
There are many higher order functions and we will look into some of them which are most widely used: map, flatMap, filter, reduce, and sorted.
map :
Returns an array containing the results of mapping the given closure over the sequence’s elements.
import Foundation
let array = [1,2,3,4,5]
//map takes closure with one argument and apply changes to each elment of array one by one.
let mappedArray = array.map({num in
num * 100
})
print(mappedArray)
//Shorthand using trailing closures for map
let mapArray = array.map{ $0 + 5 }
print(mapArray)

flatmap:
Declaration:
func flatMap<SegmentOfResult>(_ transform: (Self.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] whereSegmentOfResult : SequenceFlatMap is lot liked Map, but as name suggest it flattens the result, so if you have arrays of array(nested array) and you use flatmap then it will give concatenated array with combining all elements of nested arrays.
import Foundation
let array = [[“Dhoni”,”Ganguly”],[“Kohli”,”Rahul”], [“Yuvraj”,”Rohit”,”Bhumrah”]]
let flatmap1 = array.flatMap{$0}
print(flatmap1)
let arr = [“1”,”2",”3",”10",”Johar”,”Mon”,”12"]
let mapResult = arr.map{Int($0)}
print(mapResult)
let flatMapResult = arr.flatMap{Int($0)}
print(flatMapResult)
So we can see difference between map and flatmap, map return results without processing but flatmap is intelligent
it not only unwrap results but also removes nil from the result.

Use this method to receive a single-level collection when your transformation produces a sequence or collection for each element.
reduce:
Returns the result of combining the elements of the sequence using the given closure.
Declaration:
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result,Self.Element) throws -> Result) rethrows -> Result
import Foundation
let array = [10,2,3,1,2,3,2]
let reducedResult = array.reduce(0,{x,y in
x+y
})
print(reducedResult)
let reducedResult2 = array.reduce(1,{
$0*$1
})
print(reducedResult2 )
output:
23
720

filter:
Returns an array containing, in order, the elements of the sequence that satisfy the given predicate.
Declaration:
func filter(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> [Self.Element]import Foundation
let strArr = [“Abhishek”, “Ganga”, “Disha”, “Choi”, “Taj Mahal”]
//we want element with lenght less than equal to 5
let filteredArr = strArr.filter({name in
name.count <= 5
})
print(filteredArr)
output: [“Ganga”, “Disha”, “Choi”]

sorted(by:)
Returns the elements of the sequence, sorted using the given predicate as the comparison between elements.
import Foundation
enum HTTPResponse {
case ok
case error(Int)
}
let response : [HTTPResponse] = [.error(500), .ok, .ok, .error(404), .error(402)]
let sortedResponses = response.sorted{
switch ($0,$1){
//Order errors by code
case let (.error(codeA),.error(codeB)):
return codeA < codeB
//All successes are equivalent, so none is before any other.
case(.ok, .ok):
return false
//Order errors before successes
case(.error, .ok): return true
case(.ok, .error): return false
}
}
print(sortedResponses)
let students: Set = [“Kofi”, “Abena”, “Peter”, “Kweku”, “Akosua”, “Aakash”]
let sortedStudents = students.sorted{
$0 < $1
}
print(sortedStudents)
Output:
[HTTPResponse.error(402), HTTPResponse.error(404), HTTPResponse.error(500), HTTPResponse.ok, HTTPResponse.ok]
[“Aakash”, “Abena”, “Akosua”, “Kofi”, “Kweku”, “Peter”]

