0

I am trying to replicate this Python code in Scala:

import json

def test_json():
    parsed = json.loads("""[{"UserName":"user1","Tags":"one, two, three"},{"UserName":"user2","Tags":"one, two, three"}]""")
    tags = parsed[0]["Tags"].split(", ")
    print(tags)

test_json()

And I am coming up with this gibberish which does not work:

import scala.util.parsing.json._

def testSix: Seq[String] = {
    val parsed = JSON.parseFull("""[{"UserName":"user1","Tags":"one, two, three"},{"UserName":"user2","Tags":"one, two, three"}]""")
    parsed.map(_ match {
        case head :: tail => head
        case _ => Option.empty
    }).map(_ match {
        case m: Map[String, String] => m("Tags").split(", ")
        case _ => Option.empty
    })
}

How can I get the Tags in the first entry of the json?

2
  • Which library are you using to parse the JSON? Commented Jun 14, 2017 at 8:09
  • @YuvalItzchakov updated. Commented Jun 14, 2017 at 8:10

2 Answers 2

1

It's a not good way to use the raw scala JSON util to parse JSON, it's not type safe. maybe you can JSON4s or other library.

And there is a way to achieve this by using scala util:

  def testSix: Seq[String] = {
    val parsed = JSON.parseFull("""[{"UserName":"user1","Tags":"one, two, three"},{"UserName":"user2","Tags":"one, two, three"}]""")
    val typedResult: Option[List[Map[String, String]]] = parsed.map {
      case a: List[_] => {
        a.map {
          case t: Map[String, String] => t
        }
      }
    }
    typedResult.map(_.flatMap(_.get("Tags")).toSeq).getOrElse(Seq())
  }
  testSix.head

Explanation:

  1. parse json firstly
  2. try to convert the parsed result(type: Option[Any]) to type: Option[List[Map[String, String]]]
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, close, returns List(one, two, three, one, two, three), but I need List(one, two, three)
testSix.head.split(",\\s+").toList
0

First of all default scala.util.parsing.json._ library might be ugly in this case, still try something as below

scala> val terriblyTraversedProperty = parsed.map(_ match { case  head :: tail => head case _ => Option.empty }).map(_ match { case firstUser: Map[String, String] => firstUser("Tags") case _ => Option.empty })
terriblyTraversedProperty: Option[java.io.Serializable] = Some(one, two, three)

To split the property which is Option[String],

scala> val tags = terriblyTraversedProperty.map(_ match { case tagString: String => tagString.split(",").toList case _ => Option.empty[List[String]]} ).get
tags: Product with java.io.Serializable = List(one, " two", " three")

tags is Product with java.io.Serializable but is also an instance of List[String]

scala> tags.isInstanceOf[Seq[String]]
res35: Boolean = true

I can recommend scala json4s library if you have freedom to choose libraries,

add json4s to build.sbt,

libraryDependencies += "org.json4s" % "json4s-native_2.11" % "3.5.2"

example,

scala> import org.json4s._
import org.json4s._

scala> import org.json4s.native.JsonMethods._
import org.json4s.native.JsonMethods._

scala> val parsed = parse("""[{"UserName":"user1","Tags":"one, two, three"},{"UserName":"user2","Tags":"one, two, three"}]""")
parsed: org.json4s.JValue = JArray(List(JObject(List((UserName,JString(user1)), (Tags,JString(one, two, three)))), JObject(List((UserName,JString(user2)), (Tags,JString(one, two, three))))))

to get the property from first element

scala> parsed.values.asInstanceOf[List[Map[String, String]]](0)("Tags")
res13: String = one, two, three

5 Comments

Thanks. The Some in Some(one, two, three) is what is killing me. I want Seq[String]. I can not change libraries unfortunately.
Ok, whenever you see Some, do .map :)
@delavnog See the answer, you will love it :)
Better, thanks, but this is not Seq[String], but java.io.Serializable. I really need a simple Seq[String]
Your json has "one two three" - that's a string. If you want seq, change that to ["one", "two", "three"].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.