Xử lý Map, Filter, Reduce, Flatmap trong Swift
Bài đăng này đã không được cập nhật trong 6 năm
Introduction
Trong bài viết này tôi sẽ giới thiệu khái quát cách sử dụng các hàm map, flatmap, reduce, filter rất hữu ích trong swift khi xử lý với các đối tượng collection.
Map
Chạy 1 vòng lặp cho tất cả các phần tử trong collection và thực hiện phép toán giống nhau với từng phần tử đó. Ví dụ ta có sẵn 1 mảng, ta muốn tạo ra 1 mảng là mảng bình phương của từng phần tử trong mảng ban đầu Cách xử lý thông thường:
var numberArray = [1, 2, 3, 4, 5]
//traditional way
var squareArray: [Int] = [ ]
for number in numberArray {
squareArray.append(number * number)
}
//Result: squareArray = [1, 4, 9, 16, 25]
Sử dụng Map
var numberArray = [1, 2, 3, 4, 5]
// Cach 1
var squareArray1 = numberArray.map({ (value: Int) -> Int in
return value * value
})
//Cach 2
var squareArray2 = numberArray.map { (value: Int) in
return value * value
}
//Cach 3
var squareArray3 = numberArray.map { value in
value * value
}
//Cach 4
var squareArray4 = numberArray.map { $0 * $0 }
Trong các ví dụ trên thì map nhận các closure là các argument và trả về kết quả như cách thực hiện vòng lặp thông thường 4 cách trên là 4 cách viết hàm map khác nhau, thực hiện thì như nhau
Filter
Lọc lấy ra mảng từ collection với các element thoả điều kiện nào đó, ví dụ như lấy ra mảng các số chẵn từ 1 mảng các số cho trước, lấy ra mảng các số chia hết cho 3 từ mảng cho trước, ... Ví dụ:
let numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
//Traditional way
var evenNumberArray: [Int] = [ ]
for number in numberArray {
if (number %2 == 0) {
evenNumberArray.append(number)
}
}
//Result: evenNumberArray = [2, 4, 6, 8, 10]
Sử dụng Filter
let numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let eventNumberArray = numberArray.filter { $0 %2 == 0 }
Reduce
Kết hợp tất cả các item trong 1 collection tạo ra 1 giá trị mới Ví dụ ta muốn tính tổng tất cả các phần tử trong mảng kiểu Int
var numbers = [1, 2, 3, 4, 5]
//Tradional way
var sum = 0
for number in numbers {
sum += number
}
//sum = 15
Sử dụng reduce
var numbers = [1, 2, 3, 4, 5]
//Reduce
var sum1 = numbers.reduce(0, { $0 + $1 })
//sum1 = 15
var sum2 = number.reduce(0, +)
//sum2 = 15
Có thể sử dụng được cả với string
var stringArray = ["one", "two"]
var oneTwo = stringArray.reduce("", +)
FlatMap
Khi thực hiện trên các sequences nó sẽ flattern collection của collections Ví dụ chúng ta có 1 mảng gồm 2 phần tử là 2 mảng, chúng ta muốn kết hợp 2 mảng này lại thành 1 mảng
let arrayInArray = [[1 ,2, 3], [4, 5, 6]]
var resultArray: [Int] = [ ]
for array in arrayInArray {
resultArray += array
}
//resultArray = [1, 2, 3, 4, 5, 6]
Sử dụng flatMap
let arrayInArray = [[1 ,2, 3], [4, 5, 6]]
let flattenedArray = arrayInArray.flatMap{ $0 }
// flattenedArray = [1, 2, 3, 4, 5, 6]
Hàm flatmap xoá nil khỏi collection Ví dụ:
let people: [String?] = ["A", nil, "B", nil, "C"]
var validPeople = people.flatMap { $0 }
//varlidPeople = ["A", "B", "C"]
Chaining
Chúng ta có thể kết hợp các hàm ở trên lại với nhau Ví dụ ta muốn tính tổng bình phương của tất cả các số chẵn từ mảng của các mảng
let arrayInArray = [[1, 2, 3], [4, 5, 6]]
var resultValue = arrayInArray.flatMap{ $0 }.filter{ $0 %2 ==0 }.map{ $0 * $0}.reduce(0, +)
// resultValue = 56
Đầu tiên hàm flatMap{ $0 }tạo ra mảng [1, 2, 3, 4, 5, 6] sau đó hàm filter{ $0 %2 == 0} lấy ra các số chẵn [2, 4, 6] tiếp theo map { $0 * $0 } thực hiện bình phương [4, 16, 36] cuối cùng hàm reduce(0, +) sẽ tính tổng 4 + 16 + 36 = 56
Conclusion
Như vậy chỉ với rất ít dòng code ta đã thực hiện được rất nhiều các phép tính đối với các collection 1 cách đơn giản Tham khảo: https://medium.com/@mimicatcodes/simple-higher-order-functions-in-swift-3-0-map-filter-reduce-and-flatmap-984fa00b2532
All rights reserved