递归列表连接

And*_*ger 2 functional-programming scala

我有以下函数返回整数列表的元素之间的距离列表:

def dists(l: List[Int]) = {
  //@annotation.tailrec
  def recurse(from: Int, rest: List[Int]): List[Int] = rest match {
    case Nil => Nil
    case to :: tail => to - from :: recurse(to, tail)
  }

  l match {
    case first :: second :: _ => recurse(first, l.tail)
    case _ => Nil
  }
}
Run Code Online (Sandbox Code Playgroud)

::阻止我使用@tailrec虽然看上去调用注解recurse是在尾部位置.

是否有@tailrec兼容的方法进行连接?

我可以使用累加器但是我必须反转输入或输出,对吗?

编辑:我对递归方法特别感兴趣.我的具体用例有点复杂,因为一次调用recurse可以在结果列表中添加几个项目:

=> item1 :: item2:: recurse(...)
Run Code Online (Sandbox Code Playgroud)

距离函数只是一个证明问题的例子.

pag*_*_5b 5

这不是对确切原始请求的回复,它是该问题的替代解决方案.

您可以使用相同的列表"移位"一个位置来压缩列表,然后将生成的压缩列表映射到元组元素的差异.

在代码中

def dist(l: List[Int]) = l.zip(l drop 1) map { case (a,b) => b - a}
Run Code Online (Sandbox Code Playgroud)

如果你无法理解发生了什么,我建议拆分操作并探索REPL

scala> val l = List(1,5,8,14,19,21)
l: List[Int] = List(1, 5, 8, 14, 19, 21)

scala> l zip (l drop 1)
res1: List[(Int, Int)] = List((1,5), (5,8), (8,14), (14,19), (19,21))

scala> res1 map { case (a, b) => b - a }
res2: List[Int] = List(4, 3, 6, 5, 2)
Run Code Online (Sandbox Code Playgroud)

  • 还要记住,如果您可以使用高级操作编写显式递归,则通常不鼓励显式递归(因为它们可以在其他结构上工作,并且可能比您所做的更优化).在您的情况下,如果每次迭代需要发出多个元素,则可以轻松切换到"flatMap"而不是"map". (2认同)