首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为了理解而不调用平台图

为了理解而不调用平台图
EN

Stack Overflow用户
提问于 2015-07-15 15:31:23
回答 2查看 293关注 0票数 2

是否有一种更惯用的方式来编写反复调用的映射(而不使用flatMap)?

请参阅以下示例:

代码语言:javascript
复制
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)))

这是一个正在运行的函数,在本例中需要返回一个FutureResult。

我试过使用“用于理解”,但没有找到flatMap的应用程序。我使用flatMap的尝试使我不得不使用FutureNothing。

代码语言:javascript
复制
val futureJson : Future[Nothing] = for {
  blogList : Seq[Blog] <- futureBlogList
  blog : Blog       <- blogList
} yield {
  Json.obj("id" -> blog.id, "title" -> blog.title)
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-15 17:55:47

  • A用于理解总是多个flatMaps和一个map函数的组合。
  • 用于理解的箭头右侧的函数总是具有相同的结果类型(Seq[...]Option[...]、.)

您的工作解决方案由两个map、一个Future和一个Seq组成,因此不能将其转换为用于理解的(很好)。

关于理解的更多信息(以及与flatMap/map的转换)可以在http://www.artima.com/pins1ed/for-expressions-revisited.htmlthis question中找到。

如果您真的想使用a for理解而不是两个map,我们可以(作为一个教育练习)将第一个map转换为flatMap。然后,使用blogList的函数应该返回一个Future

代码语言:javascript
复制
futureBlogList.flatMap(blogList =>
  Future.successful(
    blogList.map(blog => Json.obj("id" -> blog.id, "title" -> blog.title))
  )
)

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

代码语言:javascript
复制
futureBlogList.flatMap(blogList =>
  Future.successful(
    for (blog <- blogList) yield Json.obj("id" -> blog.id, "title" -> blog.title)
  )
)
//.map(identity)

为了理解,我们可以将其转化为以下(相当丑陋):

代码语言:javascript
复制
for {
  blogList <- futureBlogList
  jsonBlogs <- Future.successful(
    for (blog <- blogList) yield Json.obj("id" -> blog.id, "title" -> blog.title)
  )
) yield jsonBlogs
票数 3
EN

Stack Overflow用户

发布于 2015-07-15 17:53:26

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

代码语言:javascript
复制
futurBlogList.flatMap { blogList =>
  blogList.map { blog =>
    Json.obj("id" -> blog.id, "title" -> blog.title)
  }
}

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

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

代码语言:javascript
复制
val futureResult : Future[Result] = futureBlogList.map { blogList =>
  Ok(JsArray(
    blogList.map( blog => Json.obj("id" -> blog.id, "title" -> blog.title))
  ))
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31434763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档