同时处理重复的序列
Processing sequence with duplicates concurrently
假设我有一个函数 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
一次[=26] =] 对于 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
你会如何实施它?
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)
}
解释:
as.toSet
确保每个 a
只调用一次 f
(a, (a, f(a)))
给你一个嵌套元组的集合 (a, (a, b))
- 将
a
的原始序列映射到 Map
和 (a, (a, b))
对得到一个 (a, b)
的序列。
由于您的 f
无论如何都不是异步的,并且您不介意使用期货,因此您也可以考虑使用 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
}
假设我有一个函数 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
一次[=26] =] 对于 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
你会如何实施它?
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)
}
解释:
as.toSet
确保每个a
只调用一次 (a, (a, f(a)))
给你一个嵌套元组的集合(a, (a, b))
- 将
a
的原始序列映射到Map
和(a, (a, b))
对得到一个(a, b)
的序列。
f
由于您的 f
无论如何都不是异步的,并且您不介意使用期货,因此您也可以考虑使用 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
}