如何在Scala中访问嵌套地图中的键值

时间:2019-07-29 01:53:58

标签: scala

我有一张地图清单。其中一张地图内部有另一张地图(深2级)。我需要从最内部的地图访问一些键,最后更改值。我面临的问题是从最里面的地图检索密钥。我是Scala的新手,没有运气就尝试了其他事情。

我已将“列表列表”展平,然后尝试检索键值。事实是,我可以打印整个内部地图,但不确定如何通过它进行迭代。

下面是代码:从最基本的角度来说,我想从最里面的映射中检索与键对应的值;说出键"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)
    }
  }
}

从打印stmt中可以看到,我可以打印最里面的地图的整个地图,但是在遍历过程中需要帮助。

1 个答案:

答案 0 :(得分:0)

如果在编译时知道需要更改哪些字段和值。
您可以像这样对逻辑进行硬编码:

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

注意:上面的代码片段使用了asInstanceOf之类的“不安全”技术,因为一旦您获得Map[String, Any],我们就会失去类型安全性。总是看到这样的结构,我想到了 JSON 。我建议您使用一个适当的库来管理此类数据,例如circe,而不要像上面那样编写代码。