Introduction to functional programming in Swift

Map, flatMap, Reduce and Filter.

Tung Vu Duc 🇻🇳
4 min readMay 17, 2020
photo taken by me ❤

Hôm trước mình được đề nghị tìm một số bài viết về functional programming cho các anh em dev đọc vì khách hàng đang muốn áp dụng nó vào trong dự án của họ tuy nhiên nhiều anh em chưa biết hoặc hiểu nhiều về cách sử dụng. Uhm… Mình nghĩ tại sao không viết một bài, dù sao mình cũng đã sử dụng functional programming khá lâu rồi và cảm thấy chúng rất hay và hữu dụng.

Trong bài viết này mình sẽ đề cập và đưa ra ví dụ bốn hàm mình hay sử dụng nhất: Filter, Map, Reduce, compactMap. OK, let's get it 🔥.

Skip the definition

Mình xin phép được bỏ qua định nghĩa functional programming là gì ? Các bạn có thể đọc nó ở đây. Tuy nhiên, có vài ưu điểm khi sử dụng functional programming mình muốn nêu ra ở đây:

  • Functional programming giúp code nhanh hơn, gọn hơn, nguy hiểm hơn.
  • Functional programming giúp code an toàn hơn vì tất cả những gì bạn cần làm với functional programming là đưa cho nó input và nhận về output.

Map

Hàm này được sử dụng để biến đổi từng phần tử trong một mảng sang kiểu mà bạn muốn.

Input: an array
Output: an array

Problem

Bạn có một mảng FeedItem như sau, giờ bạn muốn lấy tất cả các thumbnailURL từ mảng đó.

Imperative Approach

Functional Approach

Muốn ngắn hơn nữa ? No problem :)

Nếu bạn để ý kỹ sẽ thấy ở Functional Approach là let urls có nghĩa rằng nó an toàn hơn so với Imperative Approach bạn cần khai báo var urls vì bạn có thể chắc chắn rằng mảng urls sẽ không thể bị thay đổi… nhưng nếu bạn muốn thay đổi ? vậy bạn cũng hoàn toàn có thể khai báo var thay cho let.

Độ phức tạp: O(n) trong đó n là số phần tử của mảng đầu vào .

compactMap

Tương tự như Map nhưng compactMap thường được sử dụng để loại bỏ các giá trị optional

Input: an array
Output: an array

Problem

Cũng có một mảng FeedItem nhưng lần này thumbnailURL là biến optional, bạn muốn lấy tất cả các thumbnailURL từ mảng đó.

Imperative Approach

Functional Approach

Hoặc:

Behind the scene, compactMap thực hiện 2 vòng loop, vòng đầu tiền giống hệt với Map — biến đổi từng phần tử trong mảng sang kiểu mong muốn. Vòng loop thứ hai, nó loại bỏ tất cả các giá trị nil.

Độ phức tạp: O(m + n). Trong đó n là số phần từ của mảng input, m là số phần tử của mảng trước khi loại bỏ các item giá trị nil.

Filter

Input: an array
Output: an array

Problem

Giả sử FeedItem có thêm thuộc tính isFavorite và bạn muốn lấy ra tất cả các items có giá trị isFavorite = true

Imperative Approach

Functional Approach

Ngắn hơn:

Độ phức tạp: O(n). Trong đó n là số phần tử trong mảng đầu vào.

Reduce

Hàm này trả về kết quả sau khi kết hợp các phần tử trong một mảng thành một giá trị duy nhất.

Input: an array
Output: a single value

Problem

Tiếp tục phát triển FeedItem, thêm thuộc tính numberOfLike , giờ bạn muốn lấy được tổng số lượt thích từ mảng

Imperative Approach

Functional Approach

Áp dụng shorthand syntax:

Có thể thấy reduce nhận vào tham số là một giá trị hằng (0 trong ví dụ trên). Tham số này có ý nghĩa là giá trị khởi. Nếu ở ví dụ trên mình đặt giá trị ban đầu đó bằng 10, kết quả sẽ là 70 thay vì 60.

Độ phức tạp: O(n). Trong đó n là số phần tử của mảng đầu vào.

Conclusion

Với mình việc hiểu và sử dụng functional programming là một kỹ năng quan trọng cần phải có đặc biệt là những hàm cơ bản, bên cạnh đó mình nghĩ nó cũng không quá khó để học và áp dụng.

Vậy là chúng ta đã cùng tìm hiểu xong về bốn hàm mình thường sử dụng nhất trong công việc, ngoài ra còn rất nhiều hàm khác như: sorted, dropFirst, dropLast,… các bạn có thể tự tìm hiểu thêm nhé.

Cảm ơn các bạn đã đọc bài, đừng quên claps và chia sẻ nếu thấy bài viết hữu ích, nếu có câu hỏi hãy để lại ở phần comment ❤️.

Tham khảo:

https://developer.apple.com/

--

--

Tung Vu Duc 🇻🇳

Passionate about writing good software. Contact me: 📮tungvuduc2805@gmail.com