2

I would like to check if a Future[Seq[String]] is Empty and I am using

if(!Future.sequence(sortSeq).isEmpty){
//doSomething
}

but it throws me error ?

senia
  • 37,745
  • 4
  • 88
  • 129
princess of persia
  • 2,222
  • 4
  • 26
  • 43

2 Answers2

3

I suppose the type of sortSeq is Future[Seq[String]], so you don't need Future.sequence.

You have to wait for result of your Future and then check if result is empty:

import scala.concurrent.duration._
if(!Await.result(sortSeq.map{_.isEmpty}, 5.seconds){
  //doSomething
}

If you can execute doSomething in a different thread you could try this:

val someRusultFuture = sortSeq.map{ rs =>
  if(!rs.isEmpty){
    //doSomething
  }
}

but you'll have to wait for result of someRusultFuture.

Proof it works:

scala> import concurrent.{Future, Await}
import concurrent.{Future, Await}

scala> import scala.concurrent.duration._
import scala.concurrent.duration._

scala> val sortSeq = Future{ Thread.sleep(10000); Seq("a") }
sortSeq: scala.concurrent.Future[Seq[String]] = scala.concurrent.impl.Promise$DefaultPromise@3592f7c6

scala> Await.result(sortSeq.map{_.isEmpty}, 11.seconds)
res1: Boolean = false
senia
  • 37,745
  • 4
  • 88
  • 129
  • Note that implicit conversions are not applicable because they are ambiguous: [error] both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A] [error] and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A] [error] are possible conversion functions from scala.concurrent.Future[Seq[String]] to ?M [error] one error found – princess of persia Apr 04 '13 at 05:56
  • @princessofpersia: What is the type of sortSeq? – senia Apr 04 '13 at 05:57
  • Yes I tried that too, doesnt work. sortSeq is of type Future[Seq[String]] and I want to check if this Sequence is empty. – princess of persia Apr 04 '13 at 06:06
  • @princessofpersia: It works fine, I've added the example of code. I suppose the error is somewhere else in your code. – senia Apr 04 '13 at 06:13
0

Future.sequence method is used to transform a TraversableOnce[Future[A]] into a Future[TraversableOnce[A]].

I think you can forget whether the Seq is empty or not and just work with the Seq using the map function of Future

  val s = Future[Seq[String]](Seq("s", "e", "q"))
  val p  = s.map(s => s.foreach(println))

This works because, the empty check is performed implicitly in the background. In the below example, when the Seq is empty, nothing will be printed.

scala>   val s = Future[Seq[String]](Seq.empty)
s: scala.concurrent.Future[Seq[String]] = Future(<not completed>)

scala>   val p  = s.map(s => s.foreach(println))
p: scala.concurrent.Future[Unit] = Future(<not completed>)

If you really want to perform an empty check, you can also use withFilter.

With a non empty Seq

scala>   val s = Future[Seq[String]](Seq("s", "e", "q"))
s: scala.concurrent.Future[Seq[String]] = Future(Success(List(s, e, q)))

scala>   val p  = s.withFilter(_.nonEmpty).map(s => s.foreach(println))
p: scala.concurrent.Future[Unit] = Future(<not completed>)

s
e
q

With an empty Seq

scala>   val s = Future[Seq[String]](Seq.empty)
s: scala.concurrent.Future[Seq[String]] = Future(Success(List()))

scala>   val p  = s.withFilter(_.nonEmpty).map(s => s.foreach(println))
p: scala.concurrent.Future[Unit] = Future(<not completed>)

Also you can do the empty check as mentioned in the above answer

val someRusultFuture = sortSeq.map{ rs =>
  if(!rs.isEmpty){
    //doSomething
  }
}

Hope this helps.

tharindu_DG
  • 8,900
  • 6
  • 52
  • 64