我有一个任意嵌套的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
?
答案 0 :(得分:2)
您的代码有几个问题。首先,您使用的head
会抛出异常,在这种情况下,路径列表上没有头(如果您将错误的路径传递给该方法,则会发生这种情况)。
第二,在这里case (k: String, v: Map[String, _]) => updateMapValue(v, path.tail)
您要返回的地图类型错误,您的意思可能是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))
此方法不是堆栈安全的,因为它不是尾部递归的,但是如果您知道地图不会很深,则应该执行此操作。 不过,您可以使用 TailCalls 将其设为堆栈安全。