Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping a Scala future of a list

Tags:

scala

future

I've a list of futures, which I'd like to transform one-by-one:

def foo(x: A): Future[B] = {...}
def mapFutures(xs: Future[List[A]]): Future[List[B]]

The function mapFutures should transform each element of the list using foo, and return a future of a list. What's the best way to do this?

like image 330
thomson_matt Avatar asked Jan 11 '23 19:01

thomson_matt


2 Answers

You should be able to do what you want like this (note I specified the types A and B as Int and String to make things easier to understand):

def foo(x: Int): String = x.toString 

def mapFutures(xs: Future[List[Int]]): Future[List[String]]  = {
  for(list <- xs) yield list map foo
}

Now if you wanted something more generic, then you could define mapFutures like so:

def mapFutures[A,B](xs: Future[List[A]], f:A => B): Future[List[B]]  = {
  for(list <- xs) yield list map f
}

And then it could be used like this:

val futs = Future(List(1,2,3))
val mappedFuts = mapFutures(futs, foo)

EDIT

Now, if foo returned a Future, you could do things like this:

def foo(x: Int): Future[String] = Future(x.toString) 

def mapFutures[A,B](xs: Future[List[A]], f:A => Future[B]): Future[List[B]]  = {
  for{
    list <- xs
    mapped <- Future.sequence(list map f)
  } yield mapped
}
like image 149
cmbaxter Avatar answered Jan 17 '23 12:01

cmbaxter


Just map the future:

val futureList = Future.successful(List(1, 2, 3))
val mappedList = futureList map { _ map { _ + 1 } }    

To your specific example:

def foo(x: Int): String = x.toString
val fooList = fxs map { _ map foo }


EDIT (basically the same approach as cmbaxter; just without the for-comprehension).

For a future, you want to flatMap the sequence. Sequence converts a list of futures into a future of a list.

val fxs = Future(List(1, 2, 3))
def foo(x: Int): Future[String] = Future(x.toString)
val fooList = fxs flatMap { l => Future.sequence(l map foo) }
like image 33
Rob Napier Avatar answered Jan 17 '23 13:01

Rob Napier