Reputation: 557
I have some functions which returns list of tuple elements(Int, Int) with future. For simplicity I will define two futures
val f1 = Future {
List((8, 3), (2, 1), (4, 2), (3, 4))
}
val f2 = Future {
List((2, 3), (5, 1), (7, 9))
}
I want to filter and get the elements form these two future lists with below criteria.
Tuples which contains same element in second position
In this scenario output should be
List(((2,1),(5,1)), ((8,3),(2,3)))
I can do this with normal lists(without futures) with for comprehension like below
val l1 = List((4, 2), (3, 4), (2, 1), (8, 3))
val l2 = List((2, 3), (5, 1), (7, 9))
val o = for {
a <- l1
b <- l2 if a._2 == b._2
} yield (a, b)
How to do it with futures?
Upvotes: 0
Views: 785
Reputation: 26579
Scala 2.12 adds a zipWith
to Future
:
f1.zipWith(f2) {
(l1, l2) => for {
a <- l1
b <- l2 if a._2 == b._2
} yield (a, b)
}
For more information, see this blog post: http://viktorklang.com/blog/Futures-in-Scala-2.12-part-2.html
Upvotes: 1
Reputation: 149518
Another possibility would be the ListT
monad transformer from scalaz (although it violates the associative law):
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scalaz.Scalaz._
import scalaz._
import scala.concurrent.duration._
def main(args: Array[String]): Unit = {
val f1 = Future {
List((8, 3), (2, 1), (4, 2), (3, 4))
}
val f2 = Future {
List((2, 3), (5, 1), (7, 9))
}
val first = ListT[Future, (Int, Int)](f1)
val second = ListT[Future, (Int, Int)](f2)
val res = for {
a <- first
b <- second if a._2 == b._2
} yield (a, b)
println(Await.result(res.run, 3 seconds))
}
Upvotes: 1
Reputation: 1153
Additional solution if you want to use full for comprehension:
val o2 = for {
l1 <- f1
l2 <- f2
} yield for {
a <- l1
b <- l2 if a._2 == b._2
} yield (a,b)
Of course you will have Future here, so you need to await for result or pass it further to something which will process it
Upvotes: 3