Higher Order Functions in Swift
Higher-order functions are functions that take one or more functions as arguments, and/or return a function as their result. These functions allow you to write concise and expressive code that is easy to read and maintain.
Note:
$0 → placeholder for each item in an array
$1 → placeholder for next item in the iteration
-
map: This function applies a given transformation to each element of a collection and returns a new collection of the transformed elements.
a. Using ‘map’ to get specific properties
struct Cookie { let name: String let price: Double let quanity: Int } let order = [ Cookie(name: "Blueberry", price: 30.00, quantity: 2), Cookie(name: "Chocolate", price: 40.95, quantity: 3) ] let cookieNames = orders.map { $0.name } print(cookieNames) // ["blueberry", "Chocolate", "original", "raisins"]b. Using ‘map’ to perform a transformation → Performing certain operations on the data so that its no longer equal to the original. E.g let’s remove the 2% vat from all prices
let excludedVat = orders.map { $0.price * 0.98 } print(excludedVat) // [29.4, 40.131, 10.731, 5.684] -
filter: This function returns a new collection that contains only the elements of the original collection that satisfy a given condition → { $0.condition }
let goodCookie = order.filter { $0.name == "Chocolate"} print(goodCookie) // [Cookie(name: "Chocolate", price: 40.95, quantity: 6)] let bestCookies = order.filter {$0.quantity > 3 } print(bestCookies) // [Cookie(name: "Chocolate", price: 40.95, quantity: 6), // Cookie(name: "original", price: 10.95, quantity: 10)] -
reduce: This function combines all elements of a collection into a single value, by applying a given operation to each element in turn.
.reduce takes two parameters (initial value, operation)
let prices = [29.4, 40.131, 10.731, 5.684] let totalPrice = prices.reduce(0, +) print(totalPrice) // 85.946 let totalQuantity = orders.reduce(0, {$0 + $1.quantity}) print(totalQuantity) // 19For totalPrice we are doing a simple summation where the initial value is 0 and we are just adding the data of prices.
For totalQuantity we are adding only “quantity” for each item so basically 2 + 6…
-
flatMap: This function applies a given transformation to each element of a collection and returns a new collection that is the flattened result of the transformations.
let arrays = [ ["Penguin", "Duck", "Chicken"], ["Lion", "Leopard", "Tiger"], ["Crocodile", "Snakes", "Snails"] ] let animals = arrays.flatMap {$0} print(arrays) // [["Penguin", "Duck", "Chicken"], ["Lion", "Leopard", "Tiger"], ["Crocodile", "Snakes", "Snails"]] print(animals) // ["Penguin", "Duck", "Chicken", "Lion", "Leopard", "Tiger", "Crocodile", "Snakes", "Snails"] -
CompactMap: This function applies transformation to an array and returns a new collection of array of non-nil.
let nils = ["Apple","oranges", nil, "Strawberry", nil, nil, "Grapes"] let nonNils = nils.compactMap { $0 } print(nonNils) // ["Apple", "oranges", "Strawberry", "Grapes"] -
Combinations: combining high order functions
a. Taking the struct of Cookie as example to combine “map” and “reduce”
let totalSales = orders.map { $0.price * Double($0.quantity)}.reduce(0, +) //Total sales: 421.00000000000006
We first get sales per order by performing a map where we are multiplying the price of each item by their respective quantity. The quantity is formatted to double cause price is double, so results will be in double.
We then get total sales by adding each sales per order. To achieve this we do a reduce with operator +.
b. Taking the array of animals as example to combine “flatMap” and “filter”
let arrays = [["Penguin", "Duck", "Chicken"],["Lion", "Leopard", "Tiger"],["Crocodile", "Snakes", "Snails"]]
let animals = arrays.flatMap {$0.filter { $0.hasPrefix("C")}}
print(animals)
//["Chicken", "Crocodile"]