Reputation: 5659
I have the following function:
def countAllFriends(currUser: String, members: List[String]): Future[Map[String, Integer]] = {
val results: List[Future[List[String]]] = members.map(currUser => retrieveAllFriends( currUser))
//go through the results, and return a future of a map of usernames to the number of times that username exists in the list
}
How can I implement the function so that I get a return type of Future[Map[String, Integer]]
?
If a future fails, then I don't want the whole thing to fail, I just want to have a special entry in the map called 'failures' which will count the number of failed futures.
Upvotes: 1
Views: 1060
Reputation: 15773
First use Future.sequence
to get a Future[List[List[String]]
:
val p: Future[List[List[String]]] = Future.sequence(results)
Then flatMap
the future and the inner lists and use groupBy
and map
:
val g: Future[Map[String, Int]] = p.flatMap { listOfList =>
Future(listOfList.flatten.groupBy(identity).map(maps => (maps._1, maps._2.length)))
}
Edit:
If you want to count the number of futures failed you could use this:
val futuresWithRecover: List[Future[List[String]]] =
results.map(f => f.map(identity).recover {case _ => List("failures") })
Then the process is the same:
val p: Future[List[List[String]]] = Future.sequence(futuresWithRecover)
val g: Future[Map[String, Int]] = p.flatMap { listOfList =>
Future(listOfList.flatten.groupBy(identity).map(maps => (maps._1, maps._2.length)))
}
The second approach though is untested.
Upvotes: 3