同时处理重复项的序列

时间:2019-06-16 13:56:51

标签: scala collections concurrency future

假设我有一个函数fab: A => B,一个A序列,并且需要像这样对成对(A, B)

def foo(fab: A => B, as: Seq[A]): Seq[(A, B)] = as.zip(as.map(fab))

现在,我想使用fab同时运行scala.concurrent.Future,但是我想对fab中所有重复的元素仅运行一次as。例如,

val fab: A => B = ...
val a1: A = ...
val a2: A = ...
val as = a1 :: a1 :: a2 :: a1 :: a2 :: Nil
foo(fab, as) // invokes fab twice and run these invocations concurrently

您将如何实施?

1 个答案:

答案 0 :(得分:5)

def foo[A, B](as: Seq[A])(f: A => B)(implicit exc: ExecutionContext)
: Future[Seq[(A, B)]] = {
  Future
    .traverse(as.toSet)(a => Future((a, (a, f(a)))))
    .map(abs => as map abs.toMap)
}

说明:

  1. as.toSet确保每个f的{​​{1}}仅被调用一次
  2. a为您提供了一组形状为(a, (a, f(a)))的嵌套元组
  3. (a, (a, b))a映射Map的原始序列(a, (a, b))

由于您的(a, b)无论如何都不是异步的,并且由于您不介意使用期货,因此您也可以考虑使用f-集合:

par