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\$
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\$
  • \$\begingroup\$ How does this compare speed-wise to my solution? Scala 2.10 if it matters. \$\endgroup\$ – Martijn Apr 11 '16 at 11:39
  • \$\begingroup\$ Whoops I forgot to mention it, but yes, forall will return as soon as it encounters a false. \$\endgroup\$ – t. fochtman Apr 11 '16 at 18:08
  • \$\begingroup\$ So they are (or should be) equally fast. \$\endgroup\$ – t. fochtman Apr 11 '16 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 '16 at 18:40
  • \$\begingroup\$ I've updated my answer \$\endgroup\$ – t. fochtman Apr 13 '16 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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