Scala : yield làm việc như thế nào?

I - Khái niệm và cách sử dụng
Với mỗi lần lặp trong vòng for , yield khởi tạo 1 gía trị và được "ghi nhớ".
Giống như các vòng for có 1 bộ nhớ đệm , mỗi lần lặp của vòng lặp, một gía trị mới được "ghi nhớ".
Khi vòng lặp kết thúc ,1 collection được trả về với toàn bộ gía trị đã được ghi nhớ trước đó.
Kiểu collection được trả về cùng kiểu với collection trong vòng for,  Map trả về  Map, List trả về List vv.
Ví Dụ :
scala> val a = Array(1, 2, 3, 4, 5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for (e <- a) yield e
res5: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for (e <- a) yield e * 2
res6: Array[Int] = Array(2, 4, 6, 8, 10)

scala> for (e <- a) yield e % 2
res7: Array[Int] = Array(1, 0, 1, 0, 1)
II - Khác biệt
Sử dụng yield thường mang lại kết qủa cao hơn,code dễ đọc,dễ sửa chữa so với dùng các filter đi kèm các colection :
Ví Dụ :
ta định nghĩa 1 class : case
class Person(name: String,isMale: Boolean,children: Person*) 
khai báo 1 số value :
val lara = Person("Lara", false) 
val bob = Person("Bob", true) 
val julie = Person("Julie", false, lara, bob) 
val persons = List(lara, bob, julie) 
Bài toán : lấy ra list cặp tên mẹ và tên con :
Cách 1 : sử dụng filter đi kèm các colection :
            scala> persons filter (p => !p.isMale) flatMap (p =>(p.children map (c => (p.name, c.name))))
            res: List[(String, String)] = List((Julie,Lara),(Julie,Bob))

Cách 2 : sử dụng yield :
           scala> for (p <- persons; if !p.isMale; c <- p.children) yield (p.name, c.name)
           res6: List[(String, String)] = List((Julie,Lara),(Julie,Bob))
III - Quan trọng
Xin hãy góp ý

Comments