Scala For 循环到高阶函数

Scala For loop to Higher Order Function

我有一个书单:

case class Book(name:String,authors:List[String])

val books:List[Book] = List(
                 Book(name="Code in Scala",authors=List("Viny","Vinay")),
                 Book(name="Dance in 30 days",authors=List("Namratha","Namitha")),
                 Book(name="Cook in 30 days",authors=List("Pavan")),
                 Book(name="Gym in 30 days",authors=List("Nisanth","Vinay"))
                 ) 

现在我想知道作者名字以"Vin"开头的书。 我已经在 for 循环中实现了这个,如下所示:

for(b<-books ; a <- b.authors ; if a.startsWith("Vin")) yield b.name

但是我无法用高阶函数来实现这个。 我试过如下:

books flatMap (b=> b.authors.withFilter(a=>a.startsWith("Vin")).map(x=>x))

这让我得到了作者的名字,但我无法访问这本书 object.how 我可以解决这个问题吗? 这里的主要目标是 convert/translate 将 "for loops" 转化为高阶函数(flatmap/filter/map)

我认为 flatMap 在这里是不必要的:

scala> books.filter(_.authors.exists(_.startsWith("Vin"))).map(_.name)
res4: List[String] = List(Code in Scala, Gym in 30 days)

我认为您正在寻找 for-comprehension to combinators (map, flatmap and filter (withFilter)) 的翻译。

你快到了。缺少的部分是通过正确的范围访问图书对象:

books.flatMap(b => b.authors.withFilter(a => a.startsWith("Vin")).map(_ => b.name))

规则在 Scala language Specification(文档的第 89 页,pdf- 的第 97 页)

中进行了解释

把最后的map改成你想要的return:

books flatMap (b => b.authors.withFilter(a => a.startsWith("Vin")).map(_ => b.name))