如何从 AnyRef 类型的嵌套映射中获取值

How to get value from nested map of type AnyRef

所以我有一个类型的地图

Map[String, AnyRef]

当我通过 println 打印这张地图时,它给出了以下输出

Map(revision -> 
 Map(comment -> "string1", 
     contributor -> Map(id -> "int1", username -> "string2"), 
     format -> "string3", 
     id -> "int2", 
     minor -> None, 
     model -> "string4", 
     parentid -> "int3", 
     sha1 -> "string5", 
     text -> Map(_VALUE -> "VALUE-THAT-I-WANT-TO-GET", 
     space -> ""), 
     timestamp -> Timestamp, 
     title -> "string6"))

现在,正如您在地图中看到的那样,我想根据键 _VALUE 获取值。

我尝试按照 答案中解释的嵌套地图的方式获取它,但它不起作用可能是因为它的类型为 AnyRef
在简单的字符串变量中获取它的最佳方法是什么?

I am sorry if map is not readable enough, I will accept if you edit it in a better way. But it had be posted complete to clear sense of the problem.

详细(但明确)的版本可能是:

yourMap.get("revision") collect {
  case Some(otherMap: Map[String, AnyRef]) => otherMap.get("text")
} collect {
  case Some(yetAnotherMap: Map[String, AnyRef]) => yetAnotherMap.get("_VALUE")
}

您可以包装您的地图(别名 anymap)以定义一个 getAs[T] 方法,returns 一个 Option 等等...

import scala.reflect.ClassTag

val m: Map[String, AnyRef] = Map("a" -> Map("b" -> Map("c" -> "d")))

type AnyMap = Map[String, AnyRef]

implicit class AnyMapWrapper(m: AnyMap) {
    def getAs[T](key: String)(implicit ev: ClassTag[T]): Option[T] = m(key) match {
        case i: T => Some(i.asInstanceOf[T])
      case _ => None
  }
}

println {
    m.getAs[AnyMap]("a").flatMap(_.getAs[AnyMap]("b")).map(_("c"))
}

println {
  for {
    a <- m.getAs[AnyMap]("a")
    b <- a.getAs[AnyMap]("b")
  } yield b("c")
}

假设您有一位同事会生成这样的代码。当然,那个人会因为无能而被解雇。 las,在将其重写为适当的 Scala 之前,您会一直坚持使用它的任务。

这是您可能会做的一件事。它编译时出现警告,但似乎产生了预期的结果。

def extract(m :collection.Map[String,AnyRef], key :String) :Option[String] = {
  if (m.isDefinedAt(key)) Some(m(key).toString)
  else {
    val res = m.values
               .collect{case ma:Map[String,AnyRef] => extract(ma,key)}
               .dropWhile(_.isEmpty)
    if (res.isEmpty) None else res.head
  }
}

extract(badMap, "_VALUE") //res0: Option[String] = Some(VALUE-THAT-I-WANT-TO-GET)
extract(badMap, "_XALUE") //res1: Option[String] = None