Sourav_Bharadwaj
Sourav_Bharadwaj

Reputation: 185

Convert JSON object to List<>

I want to convert JSON object into different format. My JSON object looks like.

{
    "schema": [
        {
            "name": "cust_id",
            "data_type": "String",
            "nullable": true
        },
        {
            "name": "source_type",
            "data_type": "String",
            "nullable": true
        }
    ]
}

I want the below output:

val colType = List(("cust_id","String",true),("source_type","String",true))

I want the conversion in Scala.

Upvotes: 1

Views: 350

Answers (3)

Gustlik
Gustlik

Reputation: 360

You can use spray.json also.

Add dependency in build.sbt

libraryDependencies += "io.spray" %% "spray-json" % "1.3.6"

Application:

import spray.json._

//create your model classes
case class MyItem(name: String, data_type: String, nullable: Boolean)
case class MySchema(schema: Seq[MyItem])

//prepare JSON protocol
trait MyJsonProtocol extends DefaultJsonProtocol {
  //MyItem has 3 fields, so you have to use jsonFormat3
  implicit val myItemFormat: RootJsonFormat[MyItem] = jsonFormat3(MyItem)

  //MySchema has 1 field, so you have to use jsonFormat1
  implicit val mySchemaFormat: RootJsonFormat[MySchema] = jsonFormat1(MySchema)
}

//extends your application with your JSON protocol
object MyApplication extends App with MyJsonProtocol {
  val json =
    """{
      |"schema": [{
      |        "name": "cust_id",
      |        "data_type": "String",
      |        "nullable": true
      |    },
      |    {
      |        "name": "source_type",
      |        "data_type": "String",
      |        "nullable": true
      |    }
      |]
      |}""".stripMargin
  
  //execute parsing
  val parsed = json.parseJson.convertTo[MySchema]

  //true
  println(parsed.schema == List(MyItem("cust_id","String",true), MyItem("source_type","String",true)))
}

Upvotes: 1

Tomer Shetah
Tomer Shetah

Reputation: 8529

I'll demonstrate how can that be achieved using play-json. In case you want to serialize it into a case class, like demonstrated in the other answers, you can define the classes and their serilizers:

case class Schema(name: String, data_type: String, nullable: Boolean)

object Schema {
  implicit val format: OFormat[Schema] = Json.format[Schema]
}

case class Schemas(schema: Seq[Schema])

object Schemas {
  implicit val format: OFormat[Schemas] = Json.format[Schemas]
}

and then just call:

println(Json.parse(jsonString).as[Schemas])

Code run at Scastie.

But if you actually want list of tuples, you can do:

val path = JsPath \ "schema"

val schemas = path(Json.parse(jsonString)) match {
  case List(arr) =>
    arr match {
      case arr: JsArray =>
        arr.value.map(_.validate[JsObject] match {
          case JsSuccess(value, _) =>
            value.values.toList match {
              case List(a, b, c) =>
                (a, b, c)
              case _ => ???
            }
          case JsError(errors) =>
            ??? // Error handling
        }).toList
      case _ => ??? // Error handling
    }
  case _ => ??? // Error handling
}

Code run at Scastie

Upvotes: 1

rysh
rysh

Reputation: 131

How about using Circe?

import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
import cats.syntax.show._

case class Schema(schema: List[Container])
case class Container(name:String, data_type: String, nullable: Boolean)

val json = """
{
"schema": [{
        "name": "cust_id",
        "data_type": "String",
        "nullable": true
    },
    {
        "name": "source_type",
        "data_type": "String",
        "nullable": true
    }
]
}"""

decode[Schema](json) match {
  case Right(result) => println(result.schema.map{case Container(a,b,c) => (a,b,c)})
  case Left(failure) => println(failure.show)
    
}

Upvotes: 1

Related Questions