samba
samba

Reputation: 3111

scala - How to parse JSON string into separate records?

I wrote a method to concatenate JSON values.

def mergeSales(storeJValue: JValue): String = {
    val salesJValue: JValue = parse(rawJson)

    val store = compact(render(storeJValue))
    val sales = compact(render(salesJValue))
    val mergedSales: String = s"""{"store":$store,"sales":$sales}"""

    mergedSales
  }

As a result I'm getting strings like this, a store with an array of corresponding sales:

{"store":{"store_id":"01","name":"Store_1"}, "sales":[{"saleId": 10, "name": "New name1", "saleType": "New Type1"}, {"saleId": 20, "name": "Some name1", "saleType": "SomeType5"}, {"saleId": 30, "name": "Some name3", "saleType": "SomeType3"}]}  

How should I parse it to get a list of records where the same store is mapped to each sale from the array? I want it to look like this:

  {"store":{"store_id":"01","name":"Store_1"}, "sale":{"saleId": 10, "name": "New name1", "saleType": "New Type1"}}
  {"store":{"store_id":"01","name":"Store_1"}, "sale":{"saleId": 20, "name": "New name2", "saleType": "New Type2"}}
  {"store":{"store_id":"01","name":"Store_1"}, "sale":{"saleId": 30, "name": "Some name3", "saleType": "SomeType3"}}

Sales have a huge amount of fields in reality, so creating a case class will be rather complex.

Upvotes: 0

Views: 452

Answers (1)

Navin Gelot
Navin Gelot

Reputation: 1334

i think best way to use json4s API which will extract all your json code and convert it into map than you can easily traverse

you required to create case class :

case class Store(store_id: String, name: String)

case class Sale(saleId:String, name:String, saleType:String)

case class Result(store: Store, sale: Sale)

case class SaleStore(store: Store, sales: List[Sale])

then it is very straight forward to get solution using json4s

val str =
      """{
        |  "store": {
        |    "store_id": "01",
        |    "name": "Store_1"
        |  },
        |  "sales": [
        |    {
        |      "saleId": 10,
        |      "name": "New name1",
        |      "saleType": "New Type1"
        |    },
        |    {
        |      "saleId": 20,
        |      "name": "Some name1",
        |      "saleType": "SomeType5"
        |    },
        |    {
        |      "saleId": 30,
        |      "name": "Some name3",
        |      "saleType": "SomeType3"
        |    }
        |  ]
        |}""".stripMargin

import org.json4s._
import org.json4s.jackson.JsonMethods._
implicit val formats = org.json4s.DefaultFormats
val saleStore = parse(str).extract[SaleStore]
val result = saleStore.sales.flatMap(sale => List(saleStore.store -> sale))

val mapper: ObjectMapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)

result.map(r => mapper.writeValueAsString(Result(r._1, r._2))).foreach(println)

output:

{"store":{"store_id":"01","name":"Store_1"},"sale":{"saleId":"10","name":"New name1","saleType":"New Type1"}}
{"store":{"store_id":"01","name":"Store_1"},"sale":{"saleId":"20","name":"Some name1","saleType":"SomeType5"}}
{"store":{"store_id":"01","name":"Store_1"},"sale":{"saleId":"30","name":"Some name3","saleType":"SomeType3"}}

Upvotes: 1

Related Questions