2017-05-25 78 views
0

斯卡拉新手,繼續努力與Option相關的代碼。我有一個HashMap構建的Case類實例,它們本身包含具有Case類實例值的散列圖。這是我不清楚如何訪問檢索到的類實例的屬性:斯卡拉嵌套HashMaps,如何訪問Case 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中獲取值和屬性。

+0

你並不需要檢查是否存在的關鍵和返回無。如果密鑰不存在,HashMap將返回None。請檢查我的答案 –

回答

1

由於使用.getOrElse("someKey", None)它返回你一個類型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,(模式匹配優於鑄造)解決它只會使用.get它很聰明,給你Option[OuterClass]

scala> outerMapTest.asInstanceOf[OuterClass].nestedMap 
res30: scala.collection.mutable.HashMap[String,InnerClass] = Map(aaa -> InnerClass(xyz,0)) 

但更好的辦法,

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 
0

你想

val maybeInner = outerMap.get("AAA").flatMap(_.nestedMap.get("aaa")) 
val maybeName = maybeInner.map(_.name) 

哪,如果你的冒險的感覺,你可以用

val name: String = maybeName.get 

得到但如果它不存在,這將拋出一個錯誤。如果它的一個None

0

您可以使用下面的表達式訪問nestMap。

scala> outerMap.get("AAA").map(_.nestedMap).getOrElse(HashMap()) 
res5: scala.collection.mutable.HashMap[String,InnerClass] = Map(aaa -> InnerClass(xyz,0)) 

如果"AAA" didnt在outerMap地圖對象存在,則如在.getOrElse方法參數(HashMap())表示的以下表達式將返回一個空HashMap中。

1

這裏有一些步驟可以深入到像這樣的嵌套結構中。

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」 )。

1

一個HashMap將返回None如果key沒有找到,因此沒有必要做getOrElse返回None如果關鍵是沒有找到。

一個簡單的解決問題的方法是使用只得到如下

更改您的第一個get作爲

val outerMapTest = outerMap.get("AAA").get 

您可以檢查輸出

println(outerMapTest.name) 
println(outerMapTest.nestedMap) 

和更改秒get as

val nestedMap = outerMapTest.nestedMap.get("aaa").get 

您可以測試輸出作爲

println(nestedMap.name) 
println(nestedMap.age) 

希望這是有益

+0

謝謝 - 這主要是有效的。爲了獲得嵌套的map值,我需要'println(nestedMap.get(「aaa」)。get.name)' – rgwozdz

+0

@rgwozdz很高興聽到它幫助你儘管有上面的最佳答案。感謝upvoting。 :) –