Rjj
Rjj

Reputation: 297

How to convert json file to List using scala

I have the following json input sample.json

[{"level": 1, "firstFile": "one", "secondFile": "first"},
 {"level": 1, "firstFile": "two", "secondFile": "sec"},
 {"level": 2, "firstFile": "three", "secondFile": "third"}]

i want my result should be:

val first= List(List("one","two"),List("three"))
val second= List(List("first","sec"),List("third"))

build.sbt:

name := "Test"
version := "1.0"
scalaVersion := "2.11.0"

libraryDependencies ++= Seq("org.apache.spark" % "spark-sql_2.11" % "2.0.0" % "provided")
libraryDependencies += "com.typesafe" % "config" % "1.2.0"
libraryDependencies ++= Seq("org.slf4j" % "slf4j-api" % "1.7.5",
                            "org.clapper" %% "grizzled-slf4j" % "1.3.1")
libraryDependencies += "ch.qos.logback" % "logback-core" % "1.2.3"
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3" % "test"
libraryDependencies += "com.databricks" % "spark-avro_2.11" % "4.0.0"
libraryDependencies += "io.circe" %% "circe-config" % "0.4.1"               
retrieveManaged := true

Upvotes: 0

Views: 3141

Answers (2)

Ravinder Payal
Ravinder Payal

Reputation: 3031

Use some library for converting the Json String to a Scala object/type.

For more info: How to convert JSON to a type in Scala

Example using Lift:

import net.liftweb.json._
implicit val formats = DefaultFormats // Brings in default date formats etc.
val json = """
[{"level": 1, "firstFile": "one", "secondFile": "first"},
 {"level": 1, "firstFile": "two", "secondFile": "sec"},
 {"level": 2, "firstFile": "three", "secondFile": "third"}]
"""
case class ListSubType(level: Int, firstFile: String, secondFile: String)

val parsed: List[ListSubType] =  parse(json).extract[List[ListSubType]]
val desired: List[List[String]] = parsed.map(a => List(a.firstFile, a.secondFile))

// will produce: List(List("one", "first"), List("two", "sec"), List("three", "third"))

I know you asked different elements(of root list) in different variables, but it's better to use index or iterate over list than using different variables. Practically length of list is indefinite, so how are you gonna assign different items to different variables. Example=>

/**
* Using index
*/
val first:Option[String] = desired.get(0) // will return Option[String]
val second:Option[String] = desired.get(1) // will return Option[String]

for (items <- desired) {
   println(items)
}

Use this link to get import code for your desired build tool/package manger.

https://search.maven.org/#artifactdetails%7Cnet.liftweb%7Clift-json%7C2.0%7Cjar

Upvotes: 0

retrospectacus
retrospectacus

Reputation: 2586

Usually you convert JSON to case classes using a library like Jackson or Circe.

val json = """[{"level": 1, "firstFile": "one", "secondFile": "first"},
             | {"level": 1, "firstFile": "one", "secondFile": "first"},
             | {"level": 2, "firstFile": "two", "secondFile": "sec"},
             | {"level": 2, "firstFile": "two", "secondFile": "sec"}]""".stripMargin

case class My2FileThing(level: Int, firstFile: String, secondFile: String)

val parsed: List[My2FileThing] = {
  // TODO parse json using some library; there are many available

  List(
    My2FileThing(1, "one", "first"),
    My2FileThing(1, "one", "first"),
    My2FileThing(2, "two", "sec"),
    My2FileThing(2, "two", "sec")
  )
}

The json you provided is a one dimensional List containing four of these items, as above.

To transform that data into the two Lists you asked for, you can do this, I guess. You have not told us the logic behind your transformation.

val firstLineChandraWants: List[List[String]] =
  parsed.map(_.firstFile).groupBy(identity).values.toList
val secondLineChandraWants: List[List[String]] =
  parsed.map(_.secondFile).groupBy(identity).values.toList

Upvotes: 1

Related Questions