Scala way to program bunch of if's
It might be nicer to write it as a fold:
def balance(chars: List[Char]): Boolean = chars.foldLeft(0){
case (0, ')') => return false
case (x, ')') => x - 1
case (x, '(') => x + 1
case (x, _ ) => x
} == 0
I don't think there is any reason to filter the list before you traverse it. You can just ignore the non parentheses as you traverse the list. I think it is also unnecessary to build the second list. All you really want to know is that the count of open parenthesis is never negative:
def balance(chars: List[Char]): Boolean = {
@tailrec
def _balance(chars: List[Char], count: Int) : Boolean =
chars match {
case Nil => count == 0 // end of the string did we close every open?
case '(' :: xs => _balance(xs, count+1)
case ')' :: xs => (count > 0) && _balance(xs, count-1)
case _ => _balance(chars.tail, count) // uninteresting char, skip it
}
_balance(chars, 0)
}
Well:
- You could start by writing it with
else if
conditions. - Go ahead an annotate it with
tailrec
since it's tail-recursive. - The filter condition can be written more simply as
Set('(', ')')
, which is a function fromChar
toBoolean
- I think you're missing the condition where
chars
is empty butparenthesis
is not.
So it would look like:
def balance(chars: List[Char]): Boolean = {
@tailrec
def checkParentesys(chars: List[Char], parentesis: List[Char]): Boolean =
if (chars.isEmpty && parentesis.isEmpty)
true
else if (chars.head == '(')
checkParentesys(chars.tail, '(' :: parentesis)
else if (chars.isEmpty || parentesis.isEmpty)
false
else
checkParentesys(chars.tail, parentesis.tail)
checkParentesys(chars.filter(Set('(', ')')), List())
}
You could also just turn the whole thing into a pattern match:
def balance(chars: List[Char]): Boolean = {
@tailrec
def checkParentesys(chars: List[Char], parentesis: List[Char]): Boolean =
(chars, parentesis) match {
case (Nil, Nil) => true
case ('(' :: charsTail, _) => checkParentesys(charsTail, '(' :: parentesis)
case (Nil, _) => false
case (_, Nil) => false
case (')' :: charsTail, '(' :: parentesisTail) => checkParentesys(charsTail, parentesisTail)
}
checkParentesys(chars.filter(Set('(', ')')), List())
}