说我想简单地将字符串转换为int:
列表(“1”,“3”,“55”,“x”,“7”)=>清单(1,3,55,7)
执行此操作的一种方法是以下递归调用:
def recurse1(strs: List[String]): List[Int] = strs match {
case h :: t =>
try {
h.toInt :: recurse1(t)
}
catch {
case _ : java.lang.NumberFormatException =>
recurse1(t)
}
case _ =>
List()
}
但是由于代码中的第4行,这不能编译为尾递归。因此,为了解决这个问题,我可以按照以下方式重新定义函数:
def recurse2(strs: List[String], accum: List[Int] = List()): List[Int] = strs match {
case h :: t =>
try {
recurse2(t, h.toInt :: accum)
}
catch {
case _ : java.lang.NumberFormatException =>
recurse2(t, accum)
}
case _ =>
accum.reverse
}
所以我的问题是这个。是否有一个我可以在scala中使用的成语,它允许我递归地执行此尾部但不必传递变量来累积值?
答案 0 :(得分:1)
也许您的recurse
方法仅用于说明,但为了完整起见,我将向@ pamu添加如何使用标准函数的答案:
def foo(ss: List[String]): List[Int] =
ss.map(s => Try(s.toInt).toOption)
.filter(_.isDefined)
.map(_.get)
或
def foo(ss: List[String]): List[Int] =
ss.map(s => Try(s.toInt))
.collect { case Success(n) => n }
答案 1 :(得分:0)
通常,我看到程序员编写一个辅助函数,它接受许多参数(内部),这些参数特定于您正在使用的方法/算法。他们围绕丑陋的内部函数编写了一个最小的接口函数,它是尾递归的,只需要输入并隐藏内部机制。
def reverse(input: List[Sting]): List[Int] = {
def helper(strs: List[String], accum: List[Int] = List()): List[Int] =
strs match {
case h :: t =>
try {
helper(t, h.toInt :: accum)
}
catch {
case _ : java.lang.NumberFormatException =>
helper(t, accum)
}
case _ =>
accum.reverse
}
helper(input, List.empty[Sting])
}