如何根据 Scala 中的特定条件计算值
How to calculate a value based on certain conditions in Scala
我已经实现了一种递归方法来检查字符串中括号的数量是否有效。这是代码
def balance(chars: List[Char]): Boolean = {
@tailrec
def isValid(newChars: List[Char], difference: Int): Boolean = {
if (newChars.isEmpty) difference == 0
else if (difference < 0) false
else {
var newDifference = difference // Scala IDE gives warning here
if (newChars.head == '(') newDifference = difference + 1
else if (newChars.head == ')') newDifference = difference - 1
isValid(newChars.tail, newDifference)
}
}
isValid(chars, 0)
}
我针对以下测试用例测试了上面的代码,它工作正常所以我只是想改进 if/else 阶梯。
println("Testing parenthesis balancing")
assert(balance("(Sachin is learning (scala) and (spark))".toList))
assert(!balance("(Invalid))(expression)".toList))
assert(balance("".toList))
assert(balance("()()".toList))
assert(!balance("{())}{()}".toList))
如代码中所述,Scala IDE 在那一行抱怨
Avoid mutable local variables
我不太确定如何在不使用 if/else 的情况下计算 newDifference
的值。我可以看到的其他选项是直接调用 if/else 阶梯中的 isValid
方法,计算值是 newDifference.
我仍在学习 Scala,所以我想知道在不改变局部变量(或任何其他警告)的情况下编写此代码的最佳方法是什么。
你可以写:
val newDifference =
if (newChars.head == '(') difference + 1
else if (newChars.head == ')') difference - 1
else difference;
因为 if
在 Scala 中是一个表达式,或者使用 match
,在这种情况下会被认为更符合地道:
val newDifference = newChars.head match {
case '(' => difference + 1
case ')' => difference - 1
case _ => difference
}
整个函数可以在 newChars
上转换为单个 match
,但我会把它留给你。请参阅第一个示例 here 了解一些想法。
人们为此使用模式匹配。这样你就可以避免可变变量和 "if/else ladder",这会导致可怕的 "spaghetti code".
def isValid(chars: List[Char], ps: Int = 0) = (chars, ps) match {
case (Nil, _) => ps == 0
case (_, _) if ps < 0 => false
case ('(' :: tail, ps) => isValid(tail, ps + 1)
case (')' :: tail, ps) => isValid(tail, ps - 1)
case (_ :: tail, ps) => isValid(tail, ps)
}
我已经实现了一种递归方法来检查字符串中括号的数量是否有效。这是代码
def balance(chars: List[Char]): Boolean = {
@tailrec
def isValid(newChars: List[Char], difference: Int): Boolean = {
if (newChars.isEmpty) difference == 0
else if (difference < 0) false
else {
var newDifference = difference // Scala IDE gives warning here
if (newChars.head == '(') newDifference = difference + 1
else if (newChars.head == ')') newDifference = difference - 1
isValid(newChars.tail, newDifference)
}
}
isValid(chars, 0)
}
我针对以下测试用例测试了上面的代码,它工作正常所以我只是想改进 if/else 阶梯。
println("Testing parenthesis balancing")
assert(balance("(Sachin is learning (scala) and (spark))".toList))
assert(!balance("(Invalid))(expression)".toList))
assert(balance("".toList))
assert(balance("()()".toList))
assert(!balance("{())}{()}".toList))
如代码中所述,Scala IDE 在那一行抱怨
Avoid mutable local variables
我不太确定如何在不使用 if/else 的情况下计算 newDifference
的值。我可以看到的其他选项是直接调用 if/else 阶梯中的 isValid
方法,计算值是 newDifference.
我仍在学习 Scala,所以我想知道在不改变局部变量(或任何其他警告)的情况下编写此代码的最佳方法是什么。
你可以写:
val newDifference =
if (newChars.head == '(') difference + 1
else if (newChars.head == ')') difference - 1
else difference;
因为 if
在 Scala 中是一个表达式,或者使用 match
,在这种情况下会被认为更符合地道:
val newDifference = newChars.head match {
case '(' => difference + 1
case ')' => difference - 1
case _ => difference
}
整个函数可以在 newChars
上转换为单个 match
,但我会把它留给你。请参阅第一个示例 here 了解一些想法。
人们为此使用模式匹配。这样你就可以避免可变变量和 "if/else ladder",这会导致可怕的 "spaghetti code".
def isValid(chars: List[Char], ps: Int = 0) = (chars, ps) match {
case (Nil, _) => ps == 0
case (_, _) if ps < 0 => false
case ('(' :: tail, ps) => isValid(tail, ps + 1)
case (')' :: tail, ps) => isValid(tail, ps - 1)
case (_ :: tail, ps) => isValid(tail, ps)
}