Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - Future.sequence on Tuples

Tags:

scala

future

I have a Seq of Tuples:

val seqTuple: Seq[(String, Future[String])] = Seq(("A", Future("X")), ("B", Future("Y")))

and I want to get:

val futureSeqTuple: Future[Seq[(String, String)]] = Future(Seq(("A", "X"), ("B", "Y")))

I know I can do:

val futureSeq: Future[Seq[String]] = Future.sequence(seqTuple.map(_._2))

but I am losing the first String in the Tuple.

What is the best way to get a Future[Seq[(String, String)]]?

like image 659
Tanvir Avatar asked Mar 06 '18 02:03

Tanvir


People also ask

What is future sequence in Scala?

sequence takes a list of futures and transforms it into a single future of list in an asynchronous manner. For instance, assume that you have a list of independent jobs to be run simultaneously. In such a case, the list of futures can be composed into a single future of list using Future. sequence.

Is future onComplete blocking?

NOTE: With Future. onComplete() we are no longer blocking for the result from the Future but instead we will receive a callback for either a Success or a Failure.

When to use Scala futures?

When you want to write parallel and concurrent applications in Scala, you could still use the native Java Thread — but the Scala Future makes parallel/concurrent programming much simpler, and it's preferred.

What is the use of tuples in Scala?

In Scala, a tuple is a value that contains a fixed number of elements, each with its own type. Tuples are immutable. Tuples are especially handy for returning multiple values from a method.


2 Answers

Use the futures in tuples to map each tuple to future of tuple first, then sequence:

Future.sequence(
  seqTuple.map{case (s1, fut_s2) => fut_s2.map{s2 => (s1, s2)} }
)

Step by step, from inner terms to outer terms:

  1. The inner map converts Future("X") to Future(("A", "X")).
  2. The outer map converts each ("A", Future("X")) into an Future(("A", "X")), thus giving you a Seq[Future[(String, String)]].
  3. Now you can use sequence on that to obtain Future[Seq[(String, String)]]
like image 136
Andrey Tyukin Avatar answered Nov 08 '22 20:11

Andrey Tyukin


The answer given here works fine, but I think Future.traverse would work more succinctly here:

Future.traverse(seqTuple) {
  case (s1, s2Future) => s2Future.map{ s2 => (s1, s2) }
}

This function involves converting the input argument :)

like image 44
zkerriga Avatar answered Nov 08 '22 21:11

zkerriga