Home > database >  Best way to get List[String] or Future[List[String]] from List[Future[List[String]]] Scala
Best way to get List[String] or Future[List[String]] from List[Future[List[String]]] Scala

Time:10-19

I have a flow that returns List[Future[List[String]]] and I want to convert it to List[String] . Here's what I am doing currently to achieve it -

val functionReturnedValue: List[Future[List[String]]] = functionThatReturnsListOfFutureList()

val listBuffer = new ListBuffer[String]

functionReturnedValue.map{futureList =>
      val list = Await.result(futureList, Duration(10, "seconds"))
      list.map(string => listBuffer  = string)
    }

listBuffer.toList

Waiting inside loop is not good, also need to avoid use of ListBuffer.

Or, if it is possible to get Future[List[String]] from List[Future[List[String]]]

Could someone please help with this?

CodePudding user response:

There is no way to get a value from an asynchronus context to the synchronus context wihtout blocking the sysnchronus context to wait for the asynchronus context.

But, yes you can delay that blocking as much as you can do get better results.

val listFutureList: List[Future[List[String]]] = ???

val listListFuture: Future[List[List[String]]] = Future.sequence(listFutureList)

val listFuture: Future[List[String]] = listListFuture.map(_.flatten)

val list: List[String] = Await.result(listFuture, Duration.Inf)

CodePudding user response:

Using Await.result invokes a blocking operation, which you should avoid if you can.

Just as a side note, in your code you are using .map but as you are only interested in the (mutable) ListBuffer you can just use foreach which has Unit as a return type.

Instead of mapping and adding item per item, you can use .appendAll

functionReturnedValue.foreach(fl => 
  listBuffer.appendAll(Await.result(fl, Duration(10, "seconds")))
)

As you don't want to use ListBuffer, another way could be using .sequence is with a for comprehension and then .flatten

val fls: Future[List[String]] = for (
  lls <- Future.sequence(functionReturnedValue)
) yield lls.flatten
  • Related