Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:在嵌套映射中查找值(从JSON解析)_Json_Scala - Fatal编程技术网

Scala:在嵌套映射中查找值(从JSON解析)

Scala:在嵌套映射中查找值(从JSON解析),json,scala,Json,Scala,我将JSON转换为非常复杂的嵌套映射。 我只需要这张地图中的一个值。这是“系统”领域。 在我的示例中,值是“DEV130PHYSTEST”。 有人能帮我用Scala在地图上找到这个值吗 Some(Map(type -> SUCCESS, msg -> Container D4SContRules successfully called., result -> Map(execution-results -> Map(results -> List(Map(key -

我将JSON转换为非常复杂的嵌套映射。 我只需要这张地图中的一个值。这是“系统”领域。 在我的示例中,值是“DEV130PHYSTEST”。 有人能帮我用Scala在地图上找到这个值吗

Some(Map(type -> SUCCESS, msg -> Container D4SContRules successfully called., result -> Map(execution-results -> Map(results -> List(Map(key -> , value -> 1.0), Map(key -> output, value -> List(Map(demo.d4srules.inputObj -> Map(order -> 1.0)), Map(demo.d4srules.outputObj -> Map(system -> DEV130PHYSTEST)))), Map(key -> input, value -> Map(demo.d4srules.inputObj -> Map(order -> 1.0)))), facts -> List(Map(key -> input, value -> Map(org.drools.core.common.DefaultFactHandle -> Map(external-form -> 0:1:1400441403:1400441403:1:DEFAULT:NON_TRAIT:demo.d4srules.inputObj))))))))
作为替代方案,我们也可以从JSON开始:

{
    "type": "SUCCESS",
    "msg": "Container D4SContRules successfully called.",
    "result": {
        "execution-results": {
            "results": [{
                    "key": "",
                    "value": 1
                },
                {
                    "key": "output",
                    "value": [{
                            "demo.d4srules.inputObj": {
                                "order": 1
                            }
                        },
                        {
                            "demo.d4srules.outputObj": {
                                "system": "DEV130PHYSTEST"
                            }
                        }
                    ]
                },
                {
                    "key": "input",
                    "value": {
                        "demo.d4srules.inputObj": {
                            "order": 1
                        }
                    }
                }
            ],
            "facts": [{
                "key": "input",
                "value": {
                    "org.drools.core.common.DefaultFactHandle": {
                        "external-form": "0:1:1640380:1640380:1:DEFAULT:NON_TRAIT:demo.d4srules.inputObj"
                    }
                }
            }]
        }
    }
}

我不确定我是否理解您的问题,但如果我理解正确,您需要的是找到存储在
Map
中的键的值,该键可能位于某个复杂的层次数据结构的深处,您不知道或不想硬编码到它的路径。如果是这种情况,您可以尝试以下方法:

def findValueForKeyDeep[Key](container: Any, key: Key): Option[Any] = {
  @tailrec
  def findValueForKeyInTraversable(tr: Traversable[_], key: Key): Option[Any] = {
    if (tr.isEmpty) None
    else {
      val headRes = findValueForKeyDeep(tr.head, key)
      if (headRes.isDefined) headRes else findValueForKeyInTraversable(tr.tail, key)
    }
  }

  container match {
    case m: scala.collection.Map[Key, _] => m.get(key).orElse(findValueForKeyInTraversable(m.values, key))
    case o: Option[_] => o.flatMap(findValueForKeyDeep(_, key))
    case tr: Traversable[_] => findValueForKeyInTraversable(tr, key)
    case _ => None
  }
}
例如:

val jsonObj = Some(Map(
  "type" -> "SUCCESS",
  "msg" -> "Container D4SContRules successfully called.",
  "result" ->
    Map(
      "execution-results" ->
        Map(
          "results" -> List(
            Map(
              "key" -> "",
              "value" -> 1.0),
            Map(
              "key" -> "output",
              "value" -> List(
                Map("demo.d4srules.inputObj" -> Map("order" -> 1.0)),
                Map("demo.d4srules.outputObj" -> Map("system" -> "DEV130PHYSTEST")))),
            Map(
              "key" -> "input",
              "value" -> Map("demo.d4srules.inputObj" -> Map("order" -> 1.0)))),
          "facts" -> List(
            Map("key" -> "input",
              "value" -> Map("org.drools.core.common.DefaultFactHandle" -> Map("external-form" -> "0:1:1400441403:1400441403:1:DEFAULT:NON_TRAIT:demo.d4srules.inputObj"))))))))

println(findValueForKeyDeep(jsonObj, "system"))
println(findValueForKeyDeep(jsonObj, "external-form"))
println(findValueForKeyDeep(jsonObj, "value"))
println(findValueForKeyDeep(jsonObj, "order"))
println(findValueForKeyDeep(jsonObj, "bad key"))
一些(DEV130PHYSTEST)
一些(0:1:1400441403:1400441403:1:DEFAULT:NON_TRAIT:demo.d4srules.inputObj)
一些(1.0)
一些(1.0)

请注意,如果有多个匹配键,此代码将返回其中一些键的值(任意)。还要注意,返回类型是
Option[Any]
,但如果您确定实际类型,可以在调用后使用
asInstanceOf
对其进行强制转换

更新(查找所有匹配值)

如果你想得到所有的值,你可以很容易地做到

  def findAllValuesForKeyDeep[Key](container: Any, key: Key): List[Any] = {
    @tailrec
    def findAllValuesForKeyDeepImpl(container: Any, key: Key, acc: List[Any]): List[Any] = {
      container match {
        case m: scala.collection.Map[Key, _] => {
          val valueOption = m.get(key)
          if (valueOption.isDefined)
            valueOption.get :: acc
          else
            findAllValuesForKeyDeepImpl(m.values, key, acc)
        }
        case Some(v) => findAllValuesForKeyDeepImpl(v, key, acc)
        case tr: Traversable[_] => findAllValuesForKeyInTraversable(tr, key, acc)
        case _ => acc
      }
    }

    @tailrec
    def findAllValuesForKeyInTraversable(tr: Traversable[_], key: Key, acc: List[Any]): List[Any] = {
      if (tr.isEmpty) acc
      else {
        val headAcc = findAllValuesForKeyDeepImpl(tr.head, key, acc)
        findAllValuesForKeyInTraversable(tr.tail, key, headAcc)
      }
    }

    findAllValuesForKeyDeepImpl(container, key, List.empty[Any])
  }
但是请注意,现在您不能简单地将[Any]列表转换为更具体的内容,如果您确定知道所有元素的类型并且类型相同,请使用
map
转换以下值:

findAllValuesForKeyDeep(jsonObj, "order").map(v => v.asInstanceOf[Double])

您是否在为scala使用json库?哪一个?@Michael,如果这个答案有帮助的话,把它标记为accpedhallo@SergGr……用方法为一个键返回所有值的方式重构代码会很困难吗?你能给我一个提示或解决办法吗?Thankx@Michael,请参阅我的更新以了解
findAllValuesForKeyDeep