A preliminary study of higher order functions
In Swift, higher-order functions are as follows:
- Map: Performs a mapping in the closure for each element of a given array, returns the result of the mapping placed in the array.
- FlatMap: For each element of a given array, the mapping in the closure is performed on the result of the mapping
Merge operation,
The result of the merge operation is then returned in an array. - CompactMap: For each element of a given array, perform the mapping in the closure, will
non-empty
Mapping results placed in an array are returned. - CompactMap performs the mapping in the closure for each element of the given array, which will
non-empty
Mapping result – key value pair placed in dictionary returns. - Filter: Performs the operation in the closure for each element of the given array, and will
Qualifying elements
Put it in an array. - Reduce: For each element of a given array, perform the operations in the closure on the elements
merge
And returns the result of the merge.
Now that we have a general idea of what these functions do, let’s look at some examples of how to use them in code.
map
For the map function, the use scenario is to map the type of the array to another type. For example, if we have an array of models, and the id field of the model is a String from the server, we need to convert it to an Int in certain scenarios, and we can use the map function to do that.
struct Student {
let id: String
let name: String
let age: Int
}
let stu1 = Student(id: "1001", name: "stu1", age: 12)
let stu2 = Student(id: "1002", name: "stu2", age: 14)
let stu3 = Student(id: "1003", name: "stu3", age: 16)
let stu4 = Student(id: "1004", name: "stu4", age: 20)
let stus = [stu1, stu2, stu3, stu4]
let intIds = stus.map { (stu) in
Int(stu.id)
}
print(intIds) //[Optional(1001), Optional(1002), Optional(1003), Optional(1004)]
Copy the code
With the code above, we map the ID field from String to Int? Type, that’s not what we want for an Int. If we need to access elements and we need to unpack them, how do we map elements and automatically filter nil values? At this point, it’s compactMap’s turn.
compactMap
Let’s replace the above code with:
let intIds = stus.compactMap { (stu) in
Int(stu.id)
}
Copy the code
If we print intIds, we’ll see that it’s already an Int.
compactMapValues
For sets and arrays, you can use compactMap to get non-empty collections, but for dictionaries, this function does not work.
let dict = ["key1": 10, "key2": nil]
let result = dict.compactMap { $0 }
print(result) //[(key: "key1", value: Optional(10)), (key: "key2", value: nil)]
Copy the code
At this point, we need to use the compactMapValues function to get the non-empty dictionary.
print(result) //["key1": 10]
let result = dict.compactMapValues { $0 }
print(result) //["key1": 10]
Copy the code
flatMap
For flatMaps, the main application scenario is that you want to get an array of single-layer collections. Use the following code to see the difference between map and flapMap.
let scoresByName = ["Henk": [0, 5, 8], "John": [2, 5, 8]]
let mapped = scoresByName.map { $0.value }
// [[2, 5, 8], [0, 5, 8]]
print(mapped)
let flatMapped = scoresByName.flatMap { $0.value }
// [2, 5, 8, 0, 5, 8]
Copy the code
A map places elements directly in an array, while a flatMap tils elements in an array. Actually, s.latmap (transform) is the same as s.map.transform (transform).joined().
filter
This function is exactly what the word means: find. Returns the element that matches the criteria and places it in an array. Let’s say we want to find all students older than 18.
Let adults = stus. Filter {(stu) -> Bool in STu. age >= 18} print(adults) //Copy the code
reduce
For reduce, our usage scenario is the combination operation of elements in the array, for example, we want to calculate the age of all students together.
let totalAges = stus.reduce(0) { (result, stu) in
return result + stu.age
}
print(totalAges) // 62
Copy the code
The first argument to this function is the initial value, the first argument in the subsequent tuple is the result of each evaluation, and the second argument is the element of each iteration. Finally, the result of the calculation is returned.
Use a combination of
One of the biggest benefits of using higher-order functions is that you can do functional programming. Now let’s combine these higher-order functions through several small chestnuts.
Map String to Int and find all students with ids greater than 1002
let adults = stus.compactMap { (stu) in
Int(stu.id)
}.filter { (id) -> Bool in
id > 1002
}
print(adults) //[1003, 1004]
Copy the code
Calculate the sum of the ages of all students older than 12
let totalAge = stus.filter { (stu) -> Bool in
stu.age > 12
}.reduce(0) { (result, stu) in
return result + stu.age
}
print(totalAge) // 50
Copy the code