2015-02-10 6 views
1

С большим List[Int] я решил использовать List#grouped(Int), чтобы получить List[List[Int]]. Затем я сопоставил его, применяя функцию, List[Int] => Future[List[Int]]. Мое намерение заключалось в одновременном применении функции к подписям.Список [Future [List [Int]]] to List [Int]

Теперь у меня есть List[scala.concurrent.Future[List[Int]]].

С учетом этого типа, я бы хотел получить List[Int], чтобы собрать результаты.

Каков же идиоматический способ сделать это?

ответ

7

Я предполагаю, что вы имеете в виду Future[List[Int]] вместо List[Int]. В этом случае вы должны использовать Future.sequence, чтобы нанести карту List[Future[A]] на Future[List[A]], затем flattenList, содержащийся в одном Future.

val list: List[Future[List[Int]]] = ... 

Future.sequence(list).map(_.flatten) 

И если по каким-то причинам просто хотите удалить Future, то вам нужно заблокировать, чтобы получить его.

Await.result(Future.sequence(list).map(_.flatten), Duration.Inf) 
+1

Спасибо. «последовательность» была ключом к моему вопросу, как вы указали. 'sequence :: Monad m => [m a] -> m [a]' per [Typeclassopedia] (https://wiki.haskell.org/Typeclassopedia?) –

0
val futures = List[Future[List[Int]]] 
Future.fold(futures)(List.empty) { (l, r) => 
    l ++ r 
} onComplete { 
    case Success(r) => println(r) 
    case Failure(e) => e.printStackTrace() 
} 
1

sequence подход, предложенный @ м-г будет работать, но прохладный/идиоматических способ сделать это состоит в использовании scalaz-х traverseM вместо map с функцией:

def myFunction(li: List[Int]): Future[List[Int]] = ... 
val myList: List[List[Int]] = ... 

import scalaz._, Scalaz._ 

myList.traverseM(myFunction) //returns a Future[List[Int]] 
Смежные вопросы