Những điều cần nhớ khi sử dụng scala flatMap
Scala
50
White

LinhPT viết ngày 23/05/2015

Ở scala có một hàm hay được dùng cho Collection gọi là flatMap. Hàm này có nhiều tác dụng khá thú vị, tuy nhiên cũng có nhiều hành vi khá khó đoán trước. Bài viết này tổng hợp lại các hành vi đó của flatMap

Cơ bản

Cách sử dụng của flatMap khá đơn giản, có thể hiểu thông qua ví dụ sau:

Seq(Seq(1,2,3), Seq(4), Seq(5, 6)) flatMap { x => x }

sẽ cho kết quả là

Seq(1,2,3,4,5,6)

Một ví dụ khác:

Seq(Seq(1,2,3), Seq(), Seq(5, 6)) flatMap { x => x }

sẽ cho kết quả là

Seq(1,2,3,5,6)

Từ ví dụ trên có thể thấy scala loại bỏ các giá trị rỗng (Seq(), hoặc trong trường hợp khác có thể là None hoặc Any)
Một cách đơn giản, hàm flatMap là kết hợp của 2 hàm flattenMap

Một số hành vi / tính năng thú vị của flatMap

Ví dụ 1

Seq(Seq(1,2,3), Seq(), Seq(5,6)) flatMap { x => x.size }

Hãy đoán xem đoạn code trên sẽ cho kết quả là gì :D.
Chắc hẳn nhiều bạn sẽ đoán kết quả là Seq(3,0,2), hay chính là độ dài của 3 input Sequence.
Tuy nhiên thử chạy đoạn code trên:

scala> Seq(Seq(1,2,3), Seq(), Seq(5,6)) flatMap { x => x.size }
<console>:9: error: type mismatch;
 found   : Int
 required: scala.collection.GenTraversableOnce[?]
              Seq(Seq(1,2,3), Seq(), Seq(5,6)) flatMap { x => x.size }
                                                                ^

scala phàn nàn là block bên trong flatMap nên trả về kiểu GenTraversableOnce, trong khi chúng ta lại trả về biến Int
Trong những tình huống thế này chúng ta nên dùng map thay cho flatMap.

Tuy nhiên nếu vẫn muốn sử dụng flatMap, chúng ta có thể làm như sau:

Seq(Seq(1,2,3), Seq(), Seq(5,6)) flatMap { x => Some(x.size) }

Ví dụ 2

Hãy hình dung kết quả trả về của đoạn code:

Seq(Seq("hello", "world"), Seq("good", "morning")) flatMap { x => x.mkString(" ").toUpperCase }

Chắc hẳn sẽ có nhiều bạn đoán là :

Seq("HELLO WORLD", "GOOD MORNING")

Tuy nhiên chạy thử trên console chúng ta thu được kết quả:

Seq(H, E, L, L, O, , W, O, R, L, D, G, O, O, D, , M, O, R, N, I, N, G)

Vậy điểm đặc biêt ở đây là gì, đó chính là tính chất đặc biệt của String:

val x: scala.collection.GenTraversableOnce[Char] = "hello"

Thế nên một cách đơn giản,

Seq(Seq("hello", "world"), Seq("good", "morning"))

sẽ tương đương với

Seq(Seq(Seq("h","e","l","l","o")....))

Ví dụ 3

Seq(1,2,3,4) flatMap { x => 
  if(x % 2 == 0) Some(x) else None 
} map { x =>
  x * 2
} foreach { 
  println 
}

Đoạn code trên cho kết quả là

4, 8

Kết quả này không quá khó để hình dung. Để có được kết quả tương tự như trên chúng ta có thể dùng for loop, hoặc là map + filter cũng cho kết quả tương tự. Tuy nhiên chúng ta có thể thấy được từ ví dụ trên là để map block với flatMap, chúng ta phải trả về Some.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

LinhPT

20 bài viết.
62 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
39 3
Mình thi thoảng phải quản lý linux server, mà trong đó có một số thao tác quản lý quan trong như quản lý đĩa cứng, quản lý mạng, quản lý đường truy...
LinhPT viết 3 năm trước
39 3
White
27 2
(Ảnh) Tiêu đề chỉ là câu khách :v, thực ra là có một vài điểm về mysql explain mà chắc chưa nhiều bạn biết, tớ cũng hay quên nên note lại cho nhớ ...
LinhPT viết 3 năm trước
27 2
White
18 0
Bài viết được dịch từ http://qiita.com/sion_cojp/items/04a2aa76a1021fe77079 Điều cần nhớ trước khi đánh bất kì câu lệnh nào ①Để tránh làm nặng...
LinhPT viết hơn 1 năm trước
18 0
Bài viết liên quan
White
10 0
Kí tự Regex cơ bản Về cơ bản thì các sử lý matching của scala.util.matching.Regex sẽ được "phó thác" (delegate) cho java Regex. Bạn có thể tạo một ...
huydx viết hơn 3 năm trước
10 0
White
7 1
Trong scala kí tự _ được dùng với khá nhiều mục đích .. không liên quan đến nhau. Tạm note lại cái đã khi nào có time sẽ quay lại viết cẩn thận sa...
huydx viết hơn 3 năm trước
7 1
White
1 0
(Bài viết hơi khó hiểu, dành cho bạn nào có hứng thú với type programming trong scala với các thư viện như shapeless chẳng hạn) Thông thường với m...
huydx viết hơn 2 năm trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
20 bài viết.
62 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!