I'm using Play Framework with Scala. I have the following structure for JSON being returned by an upstream server. This is just a representation
{
"key": "some-key",
"suspendData": {
"d": [
[
"arbitrary-objects/strings"
],
[
"random-value",
[
"arbitrary-objects/strings"
],
[
[
"value1",
"important-item",
[
"important-key-1"
],
"arbitrary-values/objects"
],
[
"value2",
"important-item-2",
[
"important-key-2"
]
]
]
]
]
}
}
The only facts that I have is that the data will be located somewhere within $.suspendData.d[1]
. I know the value that I am searching for which is important-key-1
. The value can be nested deeper or it could be on a different index within `d[1]. How do I approach the problem of finding whether
I can currently only think of getting $.suspendData.d[1]
and then loop to find whether such properties exist.
Again, I can't find a proper way of doing this via JsPath. I know the JsonPath equivalent, but can't find the right way through existing Play JSON support.
Simple recursion, may be not so effective, but worked:
def findPath(key: String, path: JsPath, xs: JsValue): Option[JsPath] = {
xs match {
case o:JsObject =>
var res: Option[JsPath] = None
val it = o.fields.iterator
while (res.isEmpty && it.hasNext) {
val e = it.next()
res = findPath(key, path \ (e._1), e._2)
}
res
case JsString(x) if x==key =>
Some(path)
case JsArray(x) =>
var res: Option[JsPath] = None
val it = x.zipWithIndex.iterator
while (res.isEmpty && it.hasNext) {
val e = it.next()
res = findPath(key, path(e._2), e._1)
}
res
case _ => None
}
}
findPath("important-key-1", __, j)
findPath("important-key-2", __, j)
findPath("important-key-3", __, j)
findPath("some-key", __, j)
scala> res62: Option[play.api.libs.json.JsPath] = Some(/suspendData/d(1)(2)(0)(2)(0))
scala> res63: Option[play.api.libs.json.JsPath] = Some(/suspendData/d(1)(2)(1)(2)(0))
scala> res64: Option[play.api.libs.json.JsPath] = None
scala> res65: Option[play.api.libs.json.JsPath] = Some(/key)