首页 > 解决方案 > 在 Scala 中的 JsObject 中查找 JsValue

问题描述

如何创建一个在 JsObject 中找到 JsValue 的递归函数,例如:函数输入:JsObject 和路径作为字符串示例:

JsObject 的输入:

{
"name": "Zvi"
parents: {
 "father": {
  "name": "myFatherName",
  "dob": "10/10/70"
  }
}
}

和路径示例:

  1. path = notExistsField 输出将为 None
  2. path = name 输入将是 Some("Zvi")
  3. path = parents 输出将是
   Some({
 "father": {
  "name": "myFatherName",
  "dob": "10/10/70"
  }
})
  1. parents.father 的输出将是:
Some({
  "name": "myFatherName",
  "dob": "10/10/70"
  })
  1. parents.father.name 输出将是“myFatherName”

测试示例:

"deepSearch" - {
      val payload: JsObject = Json.parse(
        """{
          |  "key1": 1,
          |  "key2": {
          |    "key1": "value21",
          |    "key2": {
          |      "key1": 221
          |    }
          |  },
          |}""".stripMargin).as[JsObject]
      "found" - {
        "nested" in {
          // In Nested Object
          service.deepSearch(payload,"key2.key1").get shouldBe JsString("value21")
          service.deepSearch(payload,"key2.key2.key1").get shouldBe JsNumber(221)
          service.deepSearch(payload,"key2.key2").get shouldBe Json.parse("{\"key1\": 221}")
        }
        "top-level" in {
          service.deepSearch(payload,"key1").get shouldBe JsNumber(1)
        }
      }
      "not found" - {
        "nested" in {
          service.deepSearch(payload,"key2.key2.key1.notExists").isEmpty shouldBe true
          service.deepSearch(payload,"key2.key2.notExists").isEmpty shouldBe true
        }
        "top-level" in {
          service.deepSearch(payload,"Boom").isEmpty shouldBe true
        }
      }

    }

标签: jsonscala

解决方案


我做了以下实现,有没有更漂亮的代码的建议

def deepSearch(payload: JsValue, path: String): JsLookupResult = {
    path indexOf (".") match {

      // For the Base case:
      case base if base < 0 => (payload \ path)

      // For the Step case:
      case found if found >= 0 =>
        val untilFirstDot = path.substring(0, found)
        (payload \ untilFirstDot) match {
          case JsDefined(newPayload) => deepSearch(newPayload, path.substring(found + 1))
          case undefined: JsUndefined => undefined
        }
    }
  }

推荐阅读