简体   繁体   English

同时处理重复项的序列

[英]Processing sequence with duplicates concurrently

Suppose I've got a function fab: A => B , a sequence of A and need to get a sequence of pairs (A, B) like this: 假设我有一个函数fab: A => B ,一个A序列,并且需要得到一对对(A, B)像这样:

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

Now I want to run fab concurrently using scala.concurrent.Future but I want to run fab only once for all duplicate elements in as . 现在,我想使用scala.concurrent.Future同时运行fab但是对于as所有重复元素,我只希望运行一次 fab For instance, 例如,

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

How would you implement it ? 您将如何实施?

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)
}

Explanation: 说明:

  1. as.toSet ensures that f is invoked only once for each a as.toSet确保每个a仅对f调用一次
  2. The (a, (a, f(a))) gives you a set with nested tuples of shape (a, (a, b)) (a, (a, f(a)))为您提供了一组嵌套形状为(a, (a, b))元组
  3. Mapping the original sequence of a s by a Map with pairs (a, (a, b)) gives you a sequence of (a, b) s. 映射的原始序列a由A S Map与对(a, (a, b))为您提供的序列(a, b)秒。

Since your f is not asynchronous anyway, and since you don't mind using futures, you might consider using par -collections as well: 由于您的f无论如何都不是异步的,并且由于您不介意使用期货,因此您也可以考虑使用par -collections:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM