Search code examples
jsonscalaforeachspray-json

Creating JSON file with for loop in scala


My requirement is to convert two string and create a JSON file(using spray JSON) and save in a resource directory.

one input string contains the ID and other input strings contain the score and topic

id = "alpha1"
inputstring = "science 30 math 24"

Expected output JSON is

{“ContentID”: “alpha1”,
“Topics”: [
           {"Score" : 30,  "TopicID" : "Science" },
           { "Score" : 24, "TopicID" :  "math”}
          ]
}

below is the approach I have taken and am stuck in the last place

Define the case class

case class Topic(Score: String, TopicID: String)
case class Model(contentID: String, topic: Array[Topic])

implicit val topicJsonFormat: RootJsonFormat[Topic] = jsonFormat2(Topic)
implicit val modelJsonFormat: RootJsonFormat[Model] = jsonFormat2(Model)

Parsing the input string

   val a = input.split(" ").zipWithIndex.collect{case(v,i) if (i % 2 == 0) => 
     (v,i)}.map(_._1)
   val b = input.split(" ").zipWithIndex.collect{case(v,i) if (i % 2 != 0) => 
   (v,i)}.map(_._1)
   val result = a.zip(b)

And finally transversing through result

paired foreach {case (x,y) =>
      val tClass = Topic(x, y)
      val mClassJsonString = Topic(x, y).toJson.prettyPrint
      out1.write(mClassJsonString.toString)
    }

And the file is generated as

{"Score" : 30,  "TopicID" : "Science" }
{ "Score" : 24, "TopicID" :  "math”}

The problem is I am not able to add the contentID as needed above. Adding ContentId inside foreach is making contentID added multiple time.


Solution

  • You're calling toJson inside foreach creating strings and then you're appending it to buffer.

    What you probably wanted to do is to create a class (ADT) hierarchy first and then serialize it:

    val topics = paired.map(Topic)
    
    //toArray might be not necessary if topics variable is already an array
    val model = Model("alpha1", topics.toArray) 
    
    val json = model.toJson.prettyPrint
    out1.write(json.toString)