What is an efficient way to doing this using scala lift?

109 views Asked by At

I want to merge data from one json to another json utilizing scala lift. In the example below, in "jsonGroups", I want to count all the groups "tom" and "dan" are part of and insert the grpCount to "jsonNames". The println(newJson) needs to equal finalOutput. What is an efficient way to do this? I know this can be reduced to much less lines of code

val jsonNames = """
{
    "id" : "1B23423B",
    "payload" : {
        "list" : [ {
                "age" : "30",
                "name" : "tom",
            }, {
                "age" : "35",
                "name" : "dan"
            }]
    }
}
"""

val jsonGroups = """
{
    "id" : "1B23423B",
    "payload" : {
        "list" : [ {
                "group" : "baseball",
                "name" : "tom",
            }, {
                "group" : "basketball",
                "name" : "tom"
            }, {
                "group" : "football",
                "name" : "dan"
            }, {
                "group" : "hockey",
                "name" : "dan"
            }, {
                "group" : "football",
                "name" : "dan"
            }]
    }
}
"""

val finalOutput = """
{
    "id" : "1B23423B",
    "payload" : {
        "list" : [ {
                "age" : "30",
                "name" : "tom",
            "groupCnt" : 2
            }, {
                "age" : "35",
                "name" : "dan",
            "groupCnt" : 3
         }]
    }
}
"""

val jsGroups = parse(jsonGroups)
val groupList = jsGroups \ "payload" \ "list"
val groupMap = new HashMap[String, Int]
groupList.children.foreach { g =>
  val group = (g \ "group").values.toString
  val name = (g \ "name").values.toString
  Option(groupMap.get(name)) match {
    case Some(x) =>
      groupMap.put(name, x + 1)
    case None =>
      groupMap.put(name, 1)
  }
}

val jsNames = parse(jsonNames)   
val newJson = jsNames.transform({
  case dataObject @ JObject(fields) if fields.contains(JField("name", JString(name)))) =>
    val groupCnt = groupMap.get(name)
    dataObject.merge(("groupCnt" -> groupCnt))
})

println (pretty(render(newJson)))
1

There are 1 answers

2
VasiliNovikov On

There might be a lot of ways to do that. What personally I use is case classes. So,

case class JsonGroup(id: String, payload: Payload)
case class Payload(list: List[PayloadList])
case class PayloadList(group: String, name: String)
val groups: Option[JsonGroup] = jsonGroups.extractOpt[JsonGroup]

groups.foreach(group => println(group.payload.list(2).name)

After that you should do your custom logic, of course.