Scala Nested HashMaps,如何访问 Case Class 值属性?
Scala Nested HashMaps, how to access Case Class value properties?
Scala新手,继续纠结Option
相关代码。我有一个由 Case Class 实例构建的 HashMap,它们本身包含具有 Case Class 实例值的哈希映射。我不清楚如何访问检索到的 Class 个实例的属性:
import collection.mutable.HashMap
case class InnerClass(name: String, age: Int)
case class OuterClass(name: String, nestedMap: HashMap[String, InnerClass])
// Load some data...hash maps are mutable
val innerMap = new HashMap[String, InnerClass]()
innerMap += ("aaa" -> InnerClass("xyz", 0))
val outerMap = new HashMap[String, OuterClass]()
outerMap += ("AAA" -> OuterClass("XYZ", innerMap))
// Try to retrieve data
val outerMapTest = outerMap.getOrElse("AAA", None)
val nestedMap = outerMapTest.nestedMap
这会产生 error: value nestedMap is not a member of Option[ScalaFiddle.OuterClass]
// Try to retrieve data a different way
val outerMapTest = outerMap.getOrElse("AAA", None)
val nestedMap = outerMapTest.nestedMap
这会产生 error: value nestedMap is not a member of Product with Serializable
请告知我将如何访问 outerMapTest.nestedMap
。我最终还需要从 nestedMap
HashMap 中获取值和属性。
你想要
val maybeInner = outerMap.get("AAA").flatMap(_.nestedMap.get("aaa"))
val maybeName = maybeInner.map(_.name)
如果你喜欢冒险,你可以得到
val name: String = maybeName.get
但如果它不存在,那将引发错误。如果它是 None
您可以使用以下表达式访问 nestMap。
scala> outerMap.get("AAA").map(_.nestedMap).getOrElse(HashMap())
res5: scala.collection.mutable.HashMap[String,InnerClass] = Map(aaa -> InnerClass(xyz,0))
如果 "AAA"
不存在于 outerMap Map 对象中,那么下面的表达式将返回一个空的 HashMap,如 .getOrElse
方法参数 (HashMap()
) 中所示。
由于您使用的是 .getOrElse("someKey", None)
,returns 您的类型是 Product
(不是您期望的实际类型 OuterClass
)
scala> val outerMapTest = outerMap.getOrElse("AAA", None)
outerMapTest: Product with Serializable = OuterClass(XYZ,Map(aaa -> InnerClass(xyz,0)))
所以 Product
需要进行模式匹配或转换为 OuterClass
模式匹配示例
scala> outerMapTest match { case x : OuterClass => println(x.nestedMap); case _ => println("is not outerclass") }
Map(aaa -> InnerClass(xyz,0))
当 outerMapTest 为 None
时,转换示例是一个糟糕的想法(模式匹配优于转换)
scala> outerMapTest.asInstanceOf[OuterClass].nestedMap
res30: scala.collection.mutable.HashMap[String,InnerClass] = Map(aaa -> InnerClass(xyz,0))
但更好的解决方法是简单地使用 .get
,它非常聪明,可以给你 Option[OuterClass]
、
scala> outerMap.get("AAA").map(outerClass => outerClass.nestedMap)
res27: Option[scala.collection.mutable.HashMap[String,InnerClass]] = Some(Map(aaa -> InnerClass(xyz,0)))
对于不存在的密钥,给你 None
scala> outerMap.get("I dont exist").map(outerClass => outerClass.nestedMap)
res28: Option[scala.collection.mutable.HashMap[String,InnerClass]] = None
您可以采取一些步骤来深入了解这样的嵌套结构。
outerMap.lift("AAA") // Option[OuterClass]
.map(_.nestedMap) // Option[HashMap[String,InnerClass]]
.flatMap(_.lift("aaa")) // Option[InnerClass]
.map(_.name) // Option[String]
.getOrElse("no name") // String
请注意,如果内部或外部映射中的任何一个没有指定的键(分别为 "aaa" 或 "AAA"),那么整个事情将安全地生成默认字符串("no name").
如果找不到 key
,HashMap
将 return None
,因此无需执行 getOrElse
到 return None
如果找不到密钥。
解决您的问题的一个简单方法是使用 get only,如下所示
将您的第一个 get
更改为
val outerMapTest = outerMap.get("AAA").get
您可以检查输出
println(outerMapTest.name)
println(outerMapTest.nestedMap)
并将第二个 get
更改为
val nestedMap = outerMapTest.nestedMap.get("aaa").get
您可以测试输出
println(nestedMap.name)
println(nestedMap.age)
希望对您有所帮助
Scala新手,继续纠结Option
相关代码。我有一个由 Case Class 实例构建的 HashMap,它们本身包含具有 Case Class 实例值的哈希映射。我不清楚如何访问检索到的 Class 个实例的属性:
import collection.mutable.HashMap
case class InnerClass(name: String, age: Int)
case class OuterClass(name: String, nestedMap: HashMap[String, InnerClass])
// Load some data...hash maps are mutable
val innerMap = new HashMap[String, InnerClass]()
innerMap += ("aaa" -> InnerClass("xyz", 0))
val outerMap = new HashMap[String, OuterClass]()
outerMap += ("AAA" -> OuterClass("XYZ", innerMap))
// Try to retrieve data
val outerMapTest = outerMap.getOrElse("AAA", None)
val nestedMap = outerMapTest.nestedMap
这会产生 error: value nestedMap is not a member of Option[ScalaFiddle.OuterClass]
// Try to retrieve data a different way
val outerMapTest = outerMap.getOrElse("AAA", None)
val nestedMap = outerMapTest.nestedMap
这会产生 error: value nestedMap is not a member of Product with Serializable
请告知我将如何访问 outerMapTest.nestedMap
。我最终还需要从 nestedMap
HashMap 中获取值和属性。
你想要
val maybeInner = outerMap.get("AAA").flatMap(_.nestedMap.get("aaa"))
val maybeName = maybeInner.map(_.name)
如果你喜欢冒险,你可以得到
val name: String = maybeName.get
但如果它不存在,那将引发错误。如果它是 None
您可以使用以下表达式访问 nestMap。
scala> outerMap.get("AAA").map(_.nestedMap).getOrElse(HashMap())
res5: scala.collection.mutable.HashMap[String,InnerClass] = Map(aaa -> InnerClass(xyz,0))
如果 "AAA"
不存在于 outerMap Map 对象中,那么下面的表达式将返回一个空的 HashMap,如 .getOrElse
方法参数 (HashMap()
) 中所示。
由于您使用的是 .getOrElse("someKey", None)
,returns 您的类型是 Product
(不是您期望的实际类型 OuterClass
)
scala> val outerMapTest = outerMap.getOrElse("AAA", None)
outerMapTest: Product with Serializable = OuterClass(XYZ,Map(aaa -> InnerClass(xyz,0)))
所以 Product
需要进行模式匹配或转换为 OuterClass
模式匹配示例
scala> outerMapTest match { case x : OuterClass => println(x.nestedMap); case _ => println("is not outerclass") }
Map(aaa -> InnerClass(xyz,0))
当 outerMapTest 为 None
时,转换示例是一个糟糕的想法(模式匹配优于转换)
scala> outerMapTest.asInstanceOf[OuterClass].nestedMap
res30: scala.collection.mutable.HashMap[String,InnerClass] = Map(aaa -> InnerClass(xyz,0))
但更好的解决方法是简单地使用 .get
,它非常聪明,可以给你 Option[OuterClass]
、
scala> outerMap.get("AAA").map(outerClass => outerClass.nestedMap)
res27: Option[scala.collection.mutable.HashMap[String,InnerClass]] = Some(Map(aaa -> InnerClass(xyz,0)))
对于不存在的密钥,给你 None
scala> outerMap.get("I dont exist").map(outerClass => outerClass.nestedMap)
res28: Option[scala.collection.mutable.HashMap[String,InnerClass]] = None
您可以采取一些步骤来深入了解这样的嵌套结构。
outerMap.lift("AAA") // Option[OuterClass]
.map(_.nestedMap) // Option[HashMap[String,InnerClass]]
.flatMap(_.lift("aaa")) // Option[InnerClass]
.map(_.name) // Option[String]
.getOrElse("no name") // String
请注意,如果内部或外部映射中的任何一个没有指定的键(分别为 "aaa" 或 "AAA"),那么整个事情将安全地生成默认字符串("no name").
如果找不到 key
,HashMap
将 return None
,因此无需执行 getOrElse
到 return None
如果找不到密钥。
解决您的问题的一个简单方法是使用 get only,如下所示
将您的第一个 get
更改为
val outerMapTest = outerMap.get("AAA").get
您可以检查输出
println(outerMapTest.name)
println(outerMapTest.nestedMap)
并将第二个 get
更改为
val nestedMap = outerMapTest.nestedMap.get("aaa").get
您可以测试输出
println(nestedMap.name)
println(nestedMap.age)
希望对您有所帮助