合并两个Scala Future[List]

6
我需要将两个Future[List]合并为一个,我想到了下面的解决方案:
    def mergeFutureLists[X]( fl1: Future[List[X]], fl2: Future[List[X]] ): Future[List[X]] =
    {
        val lf = List( fl1, fl2 )
        val fll = Future.sequence( lf )
        return fll.map{ x => x.flatMap{ el => el } }
    }

它能够完成我想要的功能,但这是正确的操作方式吗?


5
只是一个评论:在 Scala 中不要使用 return。 - znurgl
5个回答

11
你可以等待结果,然后将它们组合成一个列表:
def mergeFutureLists[X]( fl1: Future[List[X]], fl2: Future[List[X]] ) = {
  for{
    f1Res <- fl1
    f2Res <- fl2
  } yield (f1Res ::: f2Res)
}

好的,我错了,它会给你一个结果列表而不是一个新的Future列表。你确定你需要一个新的Future列表而不是这些结果吗? - znurgl
是的,我真的需要一个 Future[List]。 - david

9
你可以使用Future.reduce
def mergeFutureLists[X]( fl1: Future[List[X]], fl2: Future[List[X]]) = {
  Future.reduce(List(fl1, fl2))(_ ++ _)
}

或者,对于任意数量的未来列表:

def mergeFutureLists[X](fl: Future[List[X]]*): Future[List[X]] = {
  Future.reduce(fl)(_ ++ _)
}

2

将两个 List 组合的最简单方法可能是使用 zip

def mergeFutureLists[X](fl1: Future[List[X]], 
                        fl2: Future[List[X]]): Future[List[X]] = 
  fl1 zip fl2 map Function.tupled(_ ++ _)

1

我不完全理解你所说的“正确”,但是似乎你正在对未来进行排序。下面是一个更通用的签名:


我不太明白您所说的“正确”是什么意思,但看起来您正在对未来进行排序。以下是一个更通用的签名:
def mergeFutureLists[X](fl1: Future[List[X]], fl2: Future[List[X]]): Future[List[X]]

可能是:

def mergeFutureLists[X](fl: Future[List[X]]*): Future[List[X]]

你的实现可以使用fold表达为:

  def mergeFutureLists[X](fl: Future[List[X]]*): Future[List[X]] = 
        Future.fold(fl)(List.empty[X])(_ ++ _)

编辑

它与@Kolmar提出的解决方案相比如何?

我们都在Future上下文中使用运算符++(列表连接)。实际上,@znurgl也在做同样的事情,只是用了伪装的:::运算符。我们三个实现的唯一区别是如何进入那个上下文,使用for-comprehensionzipfold

我提出了一个使用foldcatamorphism)的实现,适用于任意数量的参数,以推广您提出的示例。


“正确”指的是我的解决方案看起来相当复杂,可能不是实现此方法最有效的方式。 - david
我同意,flatMap嵌套在map中似乎有点复杂...你喜欢使用fold实现吗? - Filippo Vitale
它看起来确实更好;-) 但我不确定是否完全理解它的工作原理。它与@Kolmar提出的解决方案相比如何? - david

0
如果两个列表的类型相同,您可以使用Future.collect
collect接受一组相同类型的Futures,并产生该类型值序列的Future。当所有基础futures完成或任何一个失败时,此future将完成。返回的序列顺序对应于传入序列的顺序。
val combinedFuture: Future[Seq[List[X]]] =  Future.collect(Seq(fl1, fl1))

然后在future返回之后,您可以将这两个列表进行flatmap。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接