【问题标题】:Scala For loop to Higher Order FunctionScala For循环到高阶函数
【发布时间】:2016-11-24 14:02:28
【问题描述】:

我有一个书单:

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

这让我得到了作者的姓名,但我无法访问图书对象。我该如何解决这个问题? 这里的主要目标是将“for循环”转换/翻译成高阶函数(flatmap/filter/map)

【问题讨论】:

  • 如果您从第二个代码示例中删除 name 属性,您将获得 book 对象。你能用高阶函数展示你的代码吗??

标签: scala list higher-order-functions


【解决方案1】:

我认为您正在寻找将 for-comprehension 翻译成组合子(mapflatmapfilter (withFilter))。

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我认为这里不需要flatMap

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

      【讨论】:

      • 感谢您的回答,但我正在研究如何将 for 循环逻辑实现/翻译成高阶函数(map/flatmap/filter)。这是 coursera 课程的一部分。再三考虑,您的解决方案也只使用了高阶函数。
      • 我认为您不能使用高阶函数编写代码。你总是需要一些一阶函数,否则你会将什么传递给高阶函数?
      猜你喜欢
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多