Scala For循环到高阶函数

时间:2016-11-24 14:02:29

标签: scala list higher-order-functions

我有一份书籍清单:

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))

这让我得到了作者的姓名,但我无法访问图书对象。我可以解决这个问题吗? 这里的主要目标是转换/翻译&#34; for循环&#34;进入更高阶函数(flatmap / filter / map)

3 个答案:

答案 0 :(得分:2)

我认为您正在寻找for-comprehension to combinators的翻译(mapflatmapfilterwithFilter))。

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

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

规则在Scala language Specification中解释(文件第89页,pdf的第97页 - )

答案 1 :(得分:1)

只需更改最后一个map即可返回您想要的内容:

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

答案 2 :(得分:0)

我认为这里不需要flatMap

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