0

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
Rjj
  • 249
  • 1
  • 7
  • 22

2 Answers2

1

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
retrospectacus
  • 2,518
  • 1
  • 11
  • 18
  • Thanks for the reply. could you please help me how to parse the JSON. – Rjj Jul 01 '18 at 13:44
  • There are a lot of libraries available that will do this. See the link in @Ravinder's answer. Usually if you are needing to parse Json, you are writing a web server, and using a web framework, and most web frameworks include some kind of Json parser that you might as well use rather than importing something else. – retrospectacus Jul 03 '18 at 18:32
  • It looks like you have imported the Circe library which is a good popular one - you can learn how to use it here; https://circe.github.io/circe/parsing.html – retrospectacus Jul 03 '18 at 18:33
0

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

Ravinder Payal
  • 2,884
  • 31
  • 40
  • I am getting error at import net.liftweb.json._ object liftweb is not a member of package net – Rjj Jun 30 '18 at 03:39
  • @ Ravinder Payal thanks for the reply. I added libraryDependencies += "net.liftweb" %% "lift-json" % "2.4-M5" but while running the sbt i am getting error. [error] (*:update) sbt.ResolveException: unresolved dependency: net.liftweb#lift-json_2.11;2.4-M5: not found [error] Could not create Eclipse project files: [error] [Error evaluating task 'scalacOptions': error,Error evaluating task 'externalDependencyClasspath': error,Error evaluating task 'update': error,Error evaluating task 'updateClassifiers': error,Error evaluating task 'updateClassifiers': error]. Any other help? – Rjj Jul 01 '18 at 13:42
  • @Chandra Share your sbt file as a question edit, it seems you haven't mapped any central repository in your build.sbt – Ravinder Payal Jul 01 '18 at 14:21
  • added the buid.sbt file. please suggest. – Rjj Jul 02 '18 at 04:36