简体   繁体   English

从Scala中的json获取数据

[英]Get data from json in Scala

I am trying to replicate this Python code in Scala: 我正在尝试在Scala中复制此Python代码:

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? 如何在json的第一项中获取Tags

It's a not good way to use the raw scala JSON util to parse JSON , it's not type safe . 这不是使用原始scala JSON util解析JSON的好方法,它不是类型安全的 maybe you can JSON4s or other library. 也许您可以使用JSON4s或其他库。

And there is a way to achieve this by using scala util : 有一种方法可以通过使用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 首先解析json
  2. try to convert the parsed result (type: Option[Any] ) to type: Option[List[Map[String, String]]] 尝试将解析的结果 (类型: Option[Any] )转换为类型: Option[List[Map[String, String]]]

First of all default scala.util.parsing.json._ library might be ugly in this case, still try something as below 首先,默认的scala.util.parsing.json._库在这种情况下可能很难看,仍然可以尝试以下操作

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] , 要分割为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] tagsProduct with java.io.Serializable但它也是List[String]的实例

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

I can recommend scala json4s library if you have freedom to choose libraries, 如果您可以自由选择库,我可以推荐scala json4s库,

add json4s to build.sbt, json4s添加到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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM