首页 > 解决方案 > 地图不会在递归函数中添加条目

问题描述

我正在使用 scala 并希望创建一个带有函数的类,该函数可以递归地向地图添加一些东西。

class Index(val map: Map[String, String]) {

    def add(e: (String, String)): Index = {
        Index(map + (e._1 -> e._2))
    }

    def addAll(list: List[(String, String)], index: Index = Index()): Index = {
        list match {
            case ::(head, next) => addAll(next, add(head))
            case Nil => index
        }
    }
}

object Index {

    def apply(map: Map[String, String] = Map()) = {
        new Index(map)
    }
}


val index = Index()
val list = List(
  ("e1", "f1"),
  ("e2", "f2"),
  ("e3", "f3"),
)
val newIndex = index.addAll(list)
println(newIndex.map.size.toString())

我将此代码排除在打印 3 之外,因为该函数应该向地图添加 3 个条目,但实际输出为 1。我做错了什么以及如何解决?

在线小提琴:https ://scalafiddle.io/sf/eqSxPX9/0

标签: scalarecursion

解决方案


有一个简单的错误,你在add(head)哪里调用它应该是index.add(head)

但是,在编写这样的递归例程时最好使用嵌套方法,例如:

def addAll(list: List[(String, String)]): Index = {
  @annotation.tailrec
  def loop(rem: List[(String, String)], index: Index): Index = {
    rem match {
      case head :: tail => loop(tail, index.add(head))
      case Nil => index
    }
  }

  loop(list, Index())
}

这允许编译器对函数进行尾递归和优化,并且还避免了该addAll方法的虚假参数。


推荐阅读