【问题标题】:Extract nested JSON element using scala使用 scala 提取嵌套的 JSON 元素
【发布时间】:2016-12-13 05:40:58
【问题描述】:

我在 Scala 中有以下代码。我的目标是在不知道它们的数量和深度的情况下提取键的值。


    import org.json4s.jackson.JsonMethods._
    import org.json4s.{DefaultFormats, JField, JObject, JString, JValue}

    object jsonLift {

        implicit val formats = DefaultFormats

        val js = parse(
            """
    {
      "url": "imap.yahoo.com",
        "credentials": {
        "username": "myusername",
        "password": "mypassword"
         },
        "some key":{
            "other key": {
                "username": "hello"
            }
        }
    }
            """)


            def getElem(elem: String, json:JValue) = for {
                    JObject(child) <- json
                    JField(elem, JString(value)) <- child       // this does not return the expected result
    //              JField("username", JString(value)) <- child // this returns the expected result
                } yield  value


        def main(args: Array[String]) {

            val result = getElem("username", js)
            println(result)

        }
    }

上述代码的结果是List(imap.yahoo.com, myusername, mypassword, hello),这不是我所期望的。我的预期结果是List(myusername, hello)

但是,如果我直接在方法getElem 中更改变量elem,并使用我感兴趣的键(作为字符串)(例如:“用户名”),我会得到预期的结果:List(myusername, hello)这是键“用户名”的所有值。

如何通过以 JSON 键的名称作为参数调用方法 getElem 来获得预期的值列表?例如:getElem("JSON key", json)

谢谢!

【问题讨论】:

  • 预期结果应该是List(myusername, hello)

标签: json scala nested json4s


【解决方案1】:

getElem 更改为

def getElem(elem: String, json:JValue) = for {
  JObject(child) <- json
  JField(`elem`, JString(value)) <- child
} yield  value

没有 RHS 上 elem 周围的反引号,您将 type JField = (String, JValue) 的第一个元素绑定到新名称 elem 并隐藏方法参数 elem

【讨论】:

  • 我不知道使用反引号会这样工作并以这种方式匹配。很高兴知道。谢谢!
  • 我也不知道。看起来像一个scala-esque解决方案。谢谢 !!!实际上它返回了预期的结果。
【解决方案2】:

所以,这里的问题是当你使用:

JField(elem, JString(value)) <- child 

在你的 for 理解中,elem 的这个新定义掩盖了你传递给 getElem 方法的 elem

我猜你的意图是如果传递给getElem 的值elemJField 的名称相同,这将匹配。然而,这不是它的工作方式,而是符号 elem 绑定到键名。

您可以通过对上面的行稍作改动来实现您想要的效果,如下所示:

JField(key, JString(value)) <- child if key == elem

仅当JField 的名称与elem 匹配时,才会将值绑定到value

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多