scala - 递归处理scala中的嵌套列表

标签 scala recursion functional-programming lisp tail-recursion

我正在自学 scala 并努力提高我的 FP 技能。

我的引用资料之一,编程语言基础 ( available here ),有一个方便的简单递归函数列表。在第 27/50 页,我们被要求实现 swapper() 函数。

(swapper s1 s2 slist) returns a list the same as slist, but
with all occurrences of s1 replaced by s2 and all occurrences of s2 replaced by s1.


> (swapper ’a ’d ’(a b c d))
(d b c a)
> (swapper ’a ’d ’(a d () c d))
(d a () c a)
> (swapper ’x ’y ’((x) y (z (x))))
((y) x (z (y)))

在 Scala 中,这是:

swapper("a", "d", List("a","b","c","d"))
swapper("a", "d", List("a","d",List(),"c","d"))
swapper("x", "y", List( List("x"), "y", List("z", List("x"))))

我的 scala 版本处理所有版本,除了最终的 x.

def swapper(a: Any, b: Any, lst: List[Any]): List[Any] ={
   def r(subList :List[Any], acc : List[Any]): List[Any] ={
     def swap (x :Any, xs: List[Any]) =
       if(x == a){
         r(xs, acc :+ b)
       } else if (x == b) {
         r(xs, acc :+ a)
       } else {
         r(xs, acc :+ x)
       }
     subList match {
     case Nil =>
       acc
     case List(x) :: xs =>
       r(xs, r(List(x), List()) +: acc)
     case x :: xs =>
       swap(x,xs)
     //case List(x) :: xs =>
   }
   }
  r(lst, List())
}

本能地,我认为这是因为我在“case List(x)::xs”部分没有交换,但我仍在努力修复它。

更困难的是,这个案例打破了尾调用优化。我该怎么做,我可以去哪里了解有关通用解决方案的更多信息?

最佳答案

您可以将此 foldRight 与模式匹配方法结合使用:

def swapper(a:Any, b:Any, list:List[Any]):List[Any] = 
  list.foldRight(List.empty[Any]) {
    case (item, acc) if item==a => b::acc
    case (item, acc) if item==b => a::acc
    case (item:List[Any], acc) => swapper(a, b, item)::acc
    case (item, acc) => item::acc
  }     

甚至更简单(感谢@marcospereira):

def swapper(a:Any, b:Any, list:List[Any]):List[Any] = 
  list.map {
    case item if item==a => b
    case item if item==b => a
    case item:List[Any] => swapper(a, b, item)
    case item => item
  }  

关于scala - 递归处理scala中的嵌套列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39339353/

相关文章:

C++ 递归问题 <confused>

java 调用 main 方法数组参数(简单但令人困惑)

list - Scala 不可变列表添加 'Unit' 元素

functional-programming - 函数式、动态和面向方面的编程模式

scala - 自定义 'run' 类似项目的任务

Scala——不是包的成员

Scala/DataFrame/Spark : How do I express multiple conditional aggregates?

algorithm - 计算具有相互依赖关系的递归算法的复杂度

scala - 如何检查 Future[Option] 列表中是否存在 None

functional-programming - 用无限流替换符号表达式