0

I have the following JSON

{
    "record1": {
        "firstName": "John",
        "lastName": "Doe",
        "locations": {
            "29b2f2295cd74b8cbb53db4379f0d823": "New York"
        }
    },
    "record2": {
        "firstName": "Carol",
        "lastName": "Rees",
        "locations": {
            "0055bb74b4984156b821ebbea6937084": "California"
        }
    },
    "record3": {
        "firstName": "Colin",
        "lastName": "Scott",
        "locations": {
            "aba67f566fc24f8a8eb3165648ca5e4f": "Toronto",
            "b847750c565246638dbc72cb89ead227": "London"
        }
    }
}

which needs to be transformed to the following using Scala

{
    "record1": {
        "firstName": "John",
        "lastName": "Doe",
        "locations": [{
            "id" : "29b2f2295cd74b8cbb53db4379f0d823",
            "location": "New York"
        }]
    },
    "record2": {
        "firstName": "Carol",
        "lastName": "Rees",
        "locations": [{
            "id" : "0055bb74b4984156b821ebbea6937084",
            "location": "California"
        }]
    },
    "record3": {
        "firstName": "Colin",
        "lastName": "Scott",
        "locations": [{
            "id": "aba67f566fc24f8a8eb3165648ca5e4f",
            "location:" : "Toronto"
        },
            {
            "id" : "b847750c565246638dbc72cb89ead227",
            "location": "London"
        }]
    }
}

I am being new to scala, this is what I have so far

case class PersonEntry(firstName: String, lastName: String, locations: Map[String, String])

val jsonMapper = JsonMapper.builder().addModule(DefaultScalaModule).build()

val inputJson: String = "{\n    \"record1\": {\n        \"firstName\": \"John\",\n        \"lastName\": \"Doe\",\n        \"locations\": {\n            \"29b2f2295cd74b8cbb53db4379f0d823\": \"New York\"\n        }\n    },\n    \"record2\": {\n        \"firstName\": \"Carol\",\n        \"lastName\": \"Rees\",\n        \"locations\": {\n            \"0055bb74b4984156b821ebbea6937084\": \"California\"\n        }\n    },\n    \"record3\": {\n        \"firstName\": \"Colin\",\n        \"lastName\": \"Scott\",\n        \"locations\": {\n            \"aba67f566fc24f8a8eb3165648ca5e4f\": \"Toronto\",\n            \"b847750c565246638dbc72cb89ead227\": \"London\"\n        }\n    }\n}"
val parsedPerson = jsonMapper.readValue(inputJson, classOf[Map[String, Any]])
val personMap: Map[String, PersonEntry] = parsedPerson.mapValues(jsonMapper.convertValue(_, classOf[PersonEntry]))
2
  • I don't see where is spar here (you added apache-spark tag) Commented Dec 30, 2022 at 17:19
  • What JSON library are you using? Look's like Jackson, right? Commented Dec 30, 2022 at 17:31

1 Answer 1

1

There are several ways to do it. As you already have written a case class representing the input data, I would:

  • create a case class representing the output data
  • parse input as input case classes
  • map input case class to output case class
  • generate JSON for output case classes

If performance matters, you could look to work without parsing to case classes and operate directly on the JSON input but I won't explain this option.

That is, something along the lines of:

case class PersonOutput(firstName: String, lastName: String, locations: Seq[Location])

case class Location(id: String, location: String)

val output: Map[String, PersonOutput] = jsonMapper
  .readValue(inputJson, classOf[Map[String, PersonEntry]])
  .map { case (key, person) => 
    val newLocations = person.locations.map { 
      case (k, v) => Location(k, v)
    }
    key -> PersonOutput(person.firstName, person.lastName, newLocations)
  }

// Then generate JSON for output
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.