Search code examples
scalafor-comprehension

Ending a for-comprehension loop when a check on one of the items returns false


I am a bit new to Scala, so apologies if this is something a bit trivial.

I have a list of items which I want to iterate through. I to execute a check on each of the items and if just one of them fails I want the whole function to return false. So you can see this as an AND condition. I want it to be evaluated lazily, i.e. the moment I encounter the first false return false.

I am used to the for - yield syntax which filters items generated through some generator (list of items, sequence etc.). In my case however I just want to break out and return false without executing the rest of the loop. In normal Java one would just do a return false; within the loop.

In an inefficient way (i.e. not stopping when I encounter the first false item), I could do it:

   (for {
          item <- items
          if !satisfiesCondition(item)
        } yield item).isEmpty

Which is essentially saying that if no items make it through the filter all of them satisfy the condition. But this seems a bit convoluted and inefficient (consider you have 1 million items and the first one already did not satisfy the condition).

What is the best and most elegant way to do this in Scala?


Solution

  • Stopping early at the first false for a condition is done using forall in Scala. (A related question)

    Your solution rewritten:

    items.forall(satisfiesCondition)
    

    To demonstrate short-circuiting:

    List(1,2,3,4,5,6).forall { x => println(x); x < 3 }
    1
    2
    3
    res1: Boolean = false
    

    The opposite of forall is exists which stops as soon as a condition is met:

    List(1,2,3,4,5,6).exists{ x => println(x); x > 3 }
    1
    2
    3
    4
    res2: Boolean = true