2
\$\begingroup\$

I have a method in Scala that checks if a game board is full or not. To speed this method up, I return inside the nested for loop to break out of both of them and stop execution. How would I achieve this in Scala in an idiomatic way?

def isFull: Boolean = {
  for (x <- getGrid.indices) {
    for (y <- getGrid(x).indices) {
      if (getGrid(x)(y).getState.isInstanceOf[Undecided]) {
        return false
      }
    }
  }
  true
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

You can apply forall to most containers to test if every element in the container satisfies some property. forall will only evaluate x + 1 if x is true. This type of evaluation is known as short-circuit evaluation. So basically we can use this property to perform the same behavior as the if-then statement in the original code.

Notice also that I've used pattern matching to get rid of the isInstanceOf[T].

def isFull: Boolean =
  getGrid.indices.forall(x =>
    getGrid(x).indices.forall(y =>
      getGrid(x)(y).getState match {
        case xyState: Undecided => False
        case _ => True
      }
    )
  )
\$\endgroup\$
5
  • \$\begingroup\$ How does this compare speed-wise to my solution? Scala 2.10 if it matters. \$\endgroup\$
    – Martijn
    Apr 11, 2016 at 11:39
  • \$\begingroup\$ Whoops I forgot to mention it, but yes, forall will return as soon as it encounters a false. \$\endgroup\$ Apr 11, 2016 at 18:08
  • \$\begingroup\$ So they are (or should be) equally fast. \$\endgroup\$ Apr 11, 2016 at 18:09
  • \$\begingroup\$ Could you elaborate on that pattern matching statement a bit? Undecided is a sealed trait and I want to check if it is a sub class or not. \$\endgroup\$
    – Martijn
    Apr 11, 2016 at 18:40
  • \$\begingroup\$ I've updated my answer \$\endgroup\$ Apr 13, 2016 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.