scala - 递归迭代嵌套的 Map[String, Any]

标签 scala recursion

我有一个任意嵌套的Map[String, Any],我想遍历并更新给定特定路径的值。

例如,如果嵌套的Map

Map("a" -> "1", "b" -> Map("c" -> "2"))

路径是["b", "c"]我期望结果是

Map("a" -> "1", "b" -> Map("c" -> "null"))

到目前为止我尝试过的是

def updateMapValue(
                map: Map[String, Any],
                path: List[String]
              ): Map[String, Any] =
map map {
  case (k: String, v: String) =>
    if (k.contains(path.head)) k -> "null"
    else k -> v
  case (k: String, v: Map[String @unchecked, _]) => updateMapValue(v, path.tail)
}

但是我在这里得到的编译错误是

Expression of type Iterable[Equals] doesn't conform to expected type Map[String, Any]

当我尝试递归调用updateMapValue时会发生这种情况。

这里发生了什么?是否有更简单的方法来遍历嵌套的 Map

最佳答案

您的代码存在一些问题。首先,您使用的是 head ,在路径列表中没有 head 的情况下会抛出异常(如果您向方法传递了错误的路径,就会发生这种情况)。

其次,这里 case (k: String, v: Map[String, _]) => updateMapValue(v, path.tail) 您正在返回 map ,但类型错误,您的意思可能是 k -> updateMapValue(v, path.tail)

这是我的实现:

def updateMapValue(
                    map: Map[String, _],
                    path: List[String]
                  ): Map[String, _] = {

  path match { //we iterated over path getting head
    case x :: xs => map.map {
      case `x` -> (m: Map[String, _]) => x -> updateMapValue(m, xs) //if value is map go deeped
      case `x` -> (_: String) => x -> "null" //if value is String replace with "null"
      case w => w
    }
    case Nil => map
  }

}


val m = Map("a" -> "1", "b" -> Map("c" -> "2"))
val path = List("b", "c")
updateMapValue(m, path) //Map(a -> 1, b -> Map(c -> null))

此方法不是堆栈安全的,因为它不是尾递归,但如果您知道您的 map 不会很深,那么它应该可以完成这项工作。 不过,您可以使用 TailCalls 使其堆栈安全。

关于scala - 递归迭代嵌套的 Map[String, Any],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57042783/

相关文章:

scala - 如何在查询参数中喷射解码列表

php - 使用路径在 PHP 数组中进行递归搜索

scala - 如何使用scala Spark或Python Spark检查Azure Blob存储路径是否存在

scala - 展平嵌套 Scalaz 验证

ruby - 算法 - 最长摆动子序列

java - 如何根据 xlsx 工作表构建树状数据

Python:确定嵌套元组中的位置

python - 从树递归返回值列表

scala - 如何在 Apache Spark 中使用 DStream 进行特征提取

list - 检查列表是否没有间隙的函数