[英]Handle Future[Option[T]] when traversing a List
def getCommentIds(
commentTargetId: Long,
sortOrder: CommentOrderEnum): Future[Seq[CommentStatsBO]]
def getCommentDetail(commentId: Long): Future[Option[CommentDetailDTO]]
def getCommentListWithDetail(
targetId: Long,
sortOrder: CommentOrderEnum,
page: Int): Future[Seq[CommentDetailDTO]] = {
commentModel.getCommentIds(targetId, sortOrder).flatMap {
commentStatsBOSeq =>
Future.traverse(commentStatsBOSeq) { commentStatsBO =>
// commentDetail is a Future[Option[T]]
val commentDetail = getCommentDetail(commentStatsBO.iId)
commentDetail.map(commentOpt =>
commentOpt
// merge the stat info into the comment detail
.map(_.copy(replyCount = Some(commentStatsBO.replyCount)))
.getOrElse(CommentDetailDTO))
}
}
}
case class CommentDetailDTO(
id: Long,
author: JsObject,
detail: CommentDetail,
replyCount: Option[Int] = None
)
Firstly, the function getCommentIds
returns a sequence of CommentStatsBO, then traversing it and try to get detail for every comment.首先,函数getCommentIds
返回一个 CommentStatsBO 序列,然后遍历它并尝试获取每个评论的详细信息。 Here comes the question, getCommentDetail
returns a Future which contains an option since the comment maybe not found, in this case, how to filter those ones whose option is None?问题来了, getCommentDetail
返回一个包含选项的 Future,因为可能找不到注释,在这种情况下,如何过滤那些选项为 None 的选项? I have tried getOrElse
, but don't know how to define an empty object just like Json.obj()
since case class
doesn't support.我试过getOrElse
,但不知道如何像Json.obj()
一样定义一个空对象,因为case class
不支持。 Thanks!谢谢!
Don't try to do too many things at the same time, rather build the solution you need step by step.不要试图同时做太多事情,而是逐步构建您需要的解决方案。
If you do a simple Future.traverse
using just getCommentDetail
you will get a Future[Seq[Option[CommentDetailDTO]]]
which then you can map
and use collect
with the Seq
to remove the Option
如果你Future.traverse
使用getCommentDetail
做一个简单的Future.traverse
你会得到一个Future[Seq[Option[CommentDetailDTO]]]
然后你可以map
和使用collect
与Seq
来删除Option
def getCommentListWithDetail(
targetId: Long,
sortOrder: CommentOrderEnum,
page: Int
): Future[Seq[CommentDetailDTO]] =
commentModel.getCommentIds(targetId, sortOrder).flatMap { commentStatsBOSeq =>
Future.traverse(commentStatsBOSeq) { commentStatsBO =>
getCommentDetail(commentStatsBO.iId)
} map { commentOptionalDetails =>
commentOptionalDetails.collect {
case Some(commentDetail) => commentDetail
}
}
}
Or if you use cats , you can use traverseFilter
或者,如果您使用猫,则可以使用traverseFilter
import cats.syntax.all._
def getCommentListWithDetail(
targetId: Long,
sortOrder: CommentOrderEnum,
page: Int
): Future[Seq[CommentDetailDTO]] =
commentModel.getCommentIds(targetId, sortOrder).flatMap { commentStatsBOSeq =>
commentStatsBOSeq.traverseFilter(getCommentDetail)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.