geo geo - 6 months ago 39
JSON Question

Extract nested JSON element using scala

I have the following code in Scala. My goal is to extract the value(s) of a key without knowing how many and how deep they are.

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

object jsonLift {

implicit val formats = DefaultFormats

val js = parse(
"url": "",
"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)


The result of the above code is
List(, myusername, mypassword, hello)
which is not what I am expecting. My expected result is
List(myusername, hello)

However, if I change the variable
, directly inside the method
, with the key (as string) that I am interested in (Eg: "username") I get the expected result:
List(myusername, hello)
which are all the values of the key "username".

How can I get the expected list of value(s) by calling the method
with the name of the JSON key as argument? Eg:
getElem("JSON key", json)

Thank you!


Change getElem to

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

Without the backticks around elem on the RHS, you are binding the first element of type JField = (String, JValue) to a new name elem and shadowing the method parameter elem