我有一个从JSON构建的某个地图,它有一些层次结构。例如:
"2015-05": {
"129557": {
"123456": 3,
"654321": 2,
"143526": 1
}
}
它存储为嵌套地图。我想要一个简单的方法来访问密钥。我可以在每个键上进行多次检查,然后查看它是否存在,然后为第二个键执行,依此类推。然而,这似乎很麻烦。我选择做这样的事情:
def getNumFromMap(key1: String, key2: Int, key3: String): Option[Int] ={
try{
map(key1)(key2).get(key3)
}catch{
case e: Exception => None
}
}
此功能可能会被执行数百万次。使用try / catch会降低执行速度吗?是否有更好的方法来实现相同的更快?
答案 0 :(得分:8)
使用for comprehension:
type MMMap[K1, K2, K3, V] = Map[K1, Map[K2, Map[K3, V]]]
def getFromMMMap[K1, K2, K3, V](
mmmap: MMMap[K1, K2, K3, V], k1: K1, k2: K2, k3: K3
) : Option[V] =
for {
mmap <- mmmap.get(k1)
map <- mmap.get(k2)
v <- map.get(k3)
} yield v
对于MMMap[String, Int, String, Int]
:
val mmmap = Map ("a" -> Map(1 -> Map("b" -> 2)))
scala> getFromMMMap(mmmap, "a", 1, "b")
res7: Option[Int] = Some(2)
答案 1 :(得分:1)
使用for表达式怎么样?
def getNumFromMap(key1: String, key2: Int, key3: String): Option[Int] ={
for {
m1 <- map.get(1)
m2 <- m1.get(2)
m3 <- m2.get(3)
} yield m3
}
然而,如果不正确测量,很难说哪种方法更快。
答案 2 :(得分:1)
def getNumFromMap(m: Map[String, Map[Int, Map[String, Int]]], key1: String, key2: Int, key3: String): Option[Int] = {
m.get(key1).flatMap(_.get(key2)).flatMap(_.get(key3))
}
答案 3 :(得分:0)
或者,单线版:
def get3[A, B, C, V](m: Map[A,Map[B,Map[C,V]]], a:A, b:B, c:C) : Option[V] =
m.get(a).flatMap(_.get(b).flatMap(_.get(c)))
或者只是为了好玩,Pimp版
implicit final class Map3[A,B,C,V](val self : Map[A,Map[B,Map[C,V]]]) extends AnyVal {
def get3(a:A, b:B, c:C) : Option[V] =
self.get(a).flatMap(_.get(b).flatMap(_.get(c)))
}
然后:
val m : Map[Int, Map[String, Map[Boolean, Char]]] = Map(5 -> Map("a" -> Map(true -> 'c')))
m.get3(5, "a", true)