2013-07-15 48 views
3

我有一个results: List[Future[Option[T]]]它包含(并行)的计算。展平未来的期权部分[期权[期权[T]]]

我想尽快获得第一个非None结果,或者如果所有计算结果都返回None,则返回None

目前,我正在做这个(我认为是丑陋的)来处理Future.find没有找到任何结果的情况。

Future.find(results)(r => r.isDefined) map { 
    case Some(hit) => hit 
    case _ => None 
} 

这将给我一个Future[Option[T]](我想要的)。

有没有一种更简洁的方式来获得Future[Option[T]]:即不必手动变平Future[Option[Option[T]]]

+0

你能结构:

def collectFirst[A, B](futures: List[Future[A]])(pfn: PartialFunction[A, B]) (implicit ex: ExecutionContext): Future[Option[B]] = Future.find(futures)(pfn.isDefinedAt) map (_.collect(pfn)) 

在这方面,你可以修改你的问题期货中的计算,这样你可以使用'Future.firstCompletedOf'来获得你所需要的? –

+0

@RandallSchulz不是我所知道的......计算可能会返回None,我不知道哪些人会这样做(事实上,如果我事先知道这一点,我绝不会开始计算)。 – fommil

回答

1

而不是这样的专业来选择,你可以写一个通用功能,如:

collectFirst(results) { case Some(hit) => hit } 
+0

嗯,我不喜欢使用'isDefinedAt',后面跟'collect'调用相同的'pfn'。 – fommil

+0

将'collect'替换为'map'应该是安全的,因为如果'find'的内部结果是'Some',我们已经知道'pfn'是为那个值定义的。 –