代码之家  ›  专栏  ›  技术社区  ›  Michael

同时处理重复序列

  •  1
  • Michael  · 技术社区  · 5 年前

    假设我有一个函数 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 但我想跑 绝妙的 只有 一旦 对于中的所有重复元素 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 回复  |  直到 5 年前
        1
  •  5
  •   Andrey Tyukin    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 对每个 a
    2. 这个 (a, (a, f(a))) 为您提供一个具有嵌套形状元组的集合 (a, (a, b))
    3. 映射原始序列 由一个 Map 双对 (a,(a,b)) 给你一个序列 (a, b) S.

    自从你 f 反正也不是异步的,而且既然您不介意使用futures,您可以考虑使用 par -收藏:

    def foo2[A, B](as: Seq[A])(f: A => B): Seq[(A, B)] = {
      as map as.toSet.par.map((a: A) => a -> (a, f(a))).seq.toMap
    }