My function is receiving a JsValue
, now this json have lists, and this lists element could also be lists, for example:
{
"firstName": "Elon",
"lastName": "Musk",
"companies": [
{
"name": "Tesla",
"city": "San Francisco",
"offices": ["sf", "ny"],
"management": {
"loscation": "New York",
"boardMembers": [
{
"name": "John",
"age": 45
},
{
"name": "Mike",
"age": 55
},
{
"name": "Rebecca",
"age": 35
}
]
}
},
{
"name": "SpaceX",
"city": "San Francisco",
"offices": ["la", "ta"],
"management": {
"loscation": "San Mateo",
"boardMembers": [
{
"name": "Lisa",
"age": 45
},
{
"name": "Dan",
"age": 55
},
{
"name": "Henry",
"age": 35
}
]
}
}
]
}
So a company have management object, which have boardMembers list.
My function is receiving the path to this element, for example:
companies[*].management.boardMembers[*].name
I want it to return a list with all the elements of this object, so the result will be:
["John", "Mike", "Rebecca", "Lisa", "Dan", "Henry"]
It's a bit complicated, but I thought maybe play.api.libs.json._
would have some feature that could help.
thought about splitting it pathStr.split("(\\[\\*]\\.|\\[\\*])").toList
and then iterate to get all elements some how and return JsLookupResult but not sure how.
Just to clarify:
My method will receive 2 parameters, the JsValue
and the path as string def myFunc(json: JsValue, path: String)
every time I call myFunc
it can receive different path, I'm not sure what it will be only after myFunc
was called.
You can do:
val jsPath = JsPath \ "companies" \\ "management" \ "boardMembers" \\ "name"
val result = jsPath(Json.parse(input))
println(result)
Which will print the expected output. See Scastie example.
Please note the difference between \
and \\
:
To implement myFunc
you can try something like this:
def findAllValuesAtPath(jsValue: JsValue, path: String): List[JsValue] = {
val jsPath = JsPath(path
.split("\\[\\*]\\.")
.flatMap(s => s.split("\\.")
.map(RecursiveSearch)
).toList)
println(jsPath.path)
jsPath(jsValue)
}
Here is another scastie.