如何从 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
所以我有一个类型的地图
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