Xử lý Map, Filter, Reduce, Flatmap trong Swift
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. 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, ...
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.
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
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 }
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("", +)
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"]
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 * $$ } 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
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