如何在Scala中访问嵌套映射中的键值
Posted
技术标签:
【中文标题】如何在Scala中访问嵌套映射中的键值【英文标题】:how to access key values within nested map in Scala 【发布时间】:2019-12-06 08:28:25 【问题描述】:我有一个地图列表。其中一张地图里面有另一张地图(2 级深)。我需要从最里面的地图访问一些键,最后更改值。我面临的问题是从最里面的地图中检索键。我对 Scala 很陌生,但没有运气就尝试了不同的东西。
我已将 List 展平为 Map,然后尝试检索键值。问题是,我可以打印整个内部地图,但不知道如何迭代。
下面是代码:在一个非常基本的情况下,我想从最里面的地图中检索与键对应的值;说钥匙"isStudentLoankRequested"
,"schoolStructure"
。
object ListToMaps
def main(args: Array[String])
val dataInputKeysListvar = List(Map("identityKeyName" -> "MY_ID", "identityKeyValue" -> "abcd-1234-xyz"),
Map("identityKeyName" -> "OUR_ID", "identityKeyValue" -> "1234567890",
"identityInformation" -> Map("writeFrequency" -> "NEVER", "studentStatus" -> "SEP", "annualValue" -> 0,
"schoolStructure" -> "OTHER", "studentType" -> "FTS", "occupationDescription" -> "other",
"studentAccountBalanceRange" -> "string", "isStudentLoankRequested" -> "N", "schoolName" -> "myschool",
"parentsIncome" -> 100)),
Map("identityKeyName" -> "FINAL_DECISION_KEY", "identityKeyValue" -> "0000-ABCD-4567-IJKL"))
val x = dataInputKeysListvar.flatten.toMap
val y = x("identityInformation")
if (x.contains("identityInformation"))
println("value of y is" + y)
正如您从 print stmt 中看到的,我可以打印最内层地图的整个地图,但在迭代方面需要帮助。
【问题讨论】:
你到底需要用那个内部地图做什么?你累过什么没用,为什么没用? 需要更改一些值。例如,将“isStudentLoankRequested”->“N”改为“isStudentLoankRequested”->“NO”。 内部映射是可变的还是不可变的?如果是第二个,您想对更改后的地图做什么,在外部地图和列表上更新它?更改的逻辑是静态的还是动态的,例如某些输入表示字段而其他输入表示新值? 两者都是不可变的。我想更改值并传递给另一个程序。这是因为下游程序期望参数为“NO”(字符串)而不是“N”(布尔) 如果你有一个Map[String, Object]
并且你想修改地图中的值,使用可变地图可能比常规地图更容易。
【参考方案1】:
如果您在编译时知道需要更改哪些字段和值。 您可以对逻辑进行硬编码,如下所示:
def fixData(data: List[Map[String, Any]]): List[Map[String, Any]] =
data.map outerMap =>
outerMap.get("identityInformation") match
case Some(innerMap) =>
// Put as many key pairs you want to change.
// Note: if the key does not exists it will be added!
val updatedInnerMap = innerMap.asInstanceOf[Map[String, String]] ++ Map(
"isStudentLoankRequested" -> "No"
)
outerMap + ("identityInformation" -> updatedInnerMap)
case None =>
outerMap
如果要更改的键值是动态的,和/或某些内部键可能不存在,或者嵌套级别可以继续。 你可以这样做:
def updateMap(map: Map[String, Any], updates: Map[String, Any]): Map[String, Any] =
map.map
case (key, value: Map[_, _]) =>
updates.get(key) match
case Some(innerUpdates : Map[_, _]) =>
key -> updateMap(
map = value.asInstanceOf[Map[String, Any]],
updates = innerUpdates.asInstanceOf[Map[String, Any]]
)
case Some(newValue) =>
key -> newValue
case None =>
key -> value
case (key, value) =>
key -> updates.getOrElse(key, default = value)
def fixData(data: List[Map[String, Any]], updates: Map[String, Any]): List[Map[String, Any]] =
data.map(outerMap => updateMap(outerMap, updates))
注意:上面的 sn-ps 使用了像 asInstanceOf
这样的“不安全”技术,因为在你得到 Map[String, Any]
的那一刻我们就失去了类型安全性。每次看到这样的结构,我都会想到 JSON。我建议您使用适当的库来管理此类数据,例如circe,而不是像上面那样编写代码。
【讨论】:
以上是关于如何在Scala中访问嵌套映射中的键值的主要内容,如果未能解决你的问题,请参考以下文章