首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并发处理重复序列

并发处理重复序列
EN

Stack Overflow用户
提问于 2019-06-16 13:56:51
回答 1查看 82关注 0票数 2

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

代码语言:javascript
复制
def foo(fab: A => B, as: Seq[A]): Seq[(A, B)] = as.zip(as.map(fab))

现在,我希望使用fab并发运行scala.concurrent.Future,但是我只想对as中的所有重复元素运行fab一次。例如,

代码语言:javascript
复制
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

你将如何实现它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-16 14:31:27

代码语言:javascript
复制
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确保对每个a只调用一次f
  2. (a, (a, f(a)))为您提供了一个包含(a, (a, b))形状嵌套元组的集合。
  3. as的原始序列通过Map映射成对(a, (a, b)),就会得到(a, b)的序列。

由于您的f无论如何都不是异步的,而且您也不介意使用期货,所以您也可以考虑使用par-collections:

代码语言:javascript
复制
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
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56619493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档