当前位置: 首页 > 知识库问答 >
问题:

无需调用平面图即可理解

翟志新
2023-03-14

有没有更惯用的方式来编写对map的重复调用(不使用flatMap)?

请参阅以下示例:

val futureJson : Future[Seq[JsValue]] = futureBlogList.map(
                                            blogList => blogList.map(
                                                    blog => Json.obj("id" -> blog.id, "title" -> blog.title)))

val futureResult : Future[Result] = futureJson.map(jsList => Ok(JsArray(jsList)))

这是一个正在运行的函数,在这种情况下需要返回未来的[结果]。

我尝试过使用“理解”,但没有找到平面图的应用程序。我尝试使用flatMap的结果是我没有未来。

val futureJson : Future[Nothing] = for {
  blogList : Seq[Blog] <- futureBlogList
  blog : Blog       <- blogList
} yield {
  Json.obj("id" -> blog.id, "title" -> blog.title)
}

共有2个答案

秋阳旭
2023-03-14

您的理解失败的原因是它在相同类型的容器上工作。在你的示例中,您将未来与集合混合在一起。没错,两者都有map,但它们是不同类型的容器,因此它们的map/flatmap链不能互操作,因此不能一起用于理解。如果你展开了理解,你会得到

futurBlogList.flatMap { blogList =>
  blogList.map { blog =>
    Json.obj("id" -> blog.id, "title" -> blog.title)
  }
}

flatMap 期望结果是 Future[U],但内部的 map 调用返回 Seq[JSList]

最终的结果是,嵌套两种不同类型的映射是表达构造的最惯用方式。充其量,您可以将这两个调用组合成如下内容:

val futureResult : Future[Result] = futureBlogList.map { blogList =>
  Ok(JsArray(
    blogList.map( blog => Json.obj("id" -> blog.id, "title" -> blog.title))
  ))
}
赏弘
2023-03-14
  • 理解的一种方法始终是多个平面图和一个map函数的组合
  • 为便于理解,a中箭头右侧的函数始终具有相同的结果类型(Seq[…]选项[…],…)

您的工作解决方案由两个< code>map和一个< code>Future以及一个< code>Seq组成,因此它不能转换成便于理解的。

更多关于for comprehensions(以及使用< code>flatMap/map的转换)的信息可以在《Scala中的编程》、1ed和本问题中找到。

如果你真的想用a来理解而不是两个地图,我们可以(作为一个教育练习)将第一个map转换成平面地图。然后,使用博客列表的函数应返回未来

futureBlogList.flatMap(blogList =>
  Future.successful(
    blogList.map(blog => Json.obj("id" -> blog.id, "title" -> blog.title))
  )
)

我们可以将第二个映射转换为 for 表达式:

futureBlogList.flatMap(blogList =>
  Future.successful(
    for (blog <- blogList) yield Json.obj("id" -> blog.id, "title" -> blog.title)
  )
)
//.map(identity)

我们可以将其转化为以下(非常难看)来理解:

for {
  blogList <- futureBlogList
  jsonBlogs <- Future.successful(
    for (blog <- blogList) yield Json.obj("id" -> blog.id, "title" -> blog.title)
  )
) yield jsonBlogs

 类似资料:
  • 问题内容: 我正在编写一个页面,其中我只想将原始JavaScript代码用于UI,而不会受到插件或框架的干扰。 现在,我正在努力寻找一种无需使用jQuery即可平滑滚动页面的方法。 问题答案: 尝试使用此平滑滚动演示或类似的算法: 使用获取当前的最佳位置 获取元素的位置,直到要滚动到的位置: 进行for循环到达该位置,这将非常快,或者使用计时器进行平滑滚动,直到使用 安德鲁·约翰逊的原始代码:

  • 如果我想在某个任意ObservableValue已更改但基础TableView数据未更改的情况下使TableView刷新(而不调用refresh()方法),那么对提取器回调方法进行自适应是否是一个好的解决方案? 这是一个使用TableView刷新()方法的实现示例。 当之前有人问过类似的问题时,@kleopatra表示“不,永远不要使用刷新。” 我有一个底层数据没有变化的情况,只是它在TableV

  • 使用以下代码作为示例https://www.jitendrazaa.com/blog/java/snmp/create-snmp-client-in-java-using-snmp4j/当我将OID发送到空IP或没有SNMP的设备时,要监视网络,程序会引发异常。 我使用for循环读取IP。我试图以不同的方式改变执行流程,但没有成功。 该程序属于java的GetAsString方法。lang.Nul

  • 问题内容: 我们有一些页面使用ajax来加载内容,并且在某些情况下需要深度链接到页面。与其链接到“用户”并告诉人们单击“设置”, 不如 将其链接到 user.aspx#settings, 这很有帮助。 __ 为了使人们能够提供指向各节的正确链接(用于技术支持等),我将其设置为在单击按钮时自动修改URL中的哈希。当然,唯一的问题是,发生这种情况时,它还会将页面滚动到该元素。 有办法禁用它吗?到目前为

  • java中是否有一种方法可以在不修改代码的情况下打印catch块中任何异常的堆栈跟踪。我被告知有一个JVM arg可以用来生成所有异常的堆栈跟踪以供调试,尽管我在这上面找不到任何留档。我能想到的唯一解决方案是使用aspectj并在创建的任何异常上创建一个方面并打印堆栈跟踪。我希望有比方面更好的解决方案。 谢了Steve --编辑——我想知道的是,假设我有以下代码:试试{throw new Exce

  • 问题内容: 所以: 我曾经使用xmail(),当我在此处添加附件时,我传递了文件名和应该包含在其中的内容。 像这样: 如何使它以相同的方式工作,所以当我从PHPmailer类进行调用时,我可以传递相同的内容或类似的内容,因此不需要在服务器上发送实际文件? 问题答案: 例如 http://phpmailer.worxware.com/index.php?pg=tutorial#3