Scala - 如何将 json 作为输入参数并解析它?
Scala - how to take json as input arguments and parse it?
我正在编写一个小的 scala 练习代码,我的输入将成为时尚 -
{
"code": "",
"unique ID": "",
"count": "",
"names": [
{
"Matt": {
"name": "Matt",
"properties": [
"a",
"b",
"c"
],
"fav-colour": "red"
},
"jack": {
"name": "jack",
"properties": [
"a",
"b"
],
"fav-colour": "blue"
}
}
]
}
我会将此文件作为命令行参数传递。
我想知道如何接受输入文件解析 json 并在我的代码中使用 json 键?
您可以使用 json 库,例如 play-json 来解析 json 内容。
您可以对 json AST 进行操作,或者您可以编写与 json 文件具有相同结构的 case classes 并让它们被解析。
您可以找到库的文档 here。
您首先必须将 playjson 作为依赖项添加到您的项目中。如果您使用的是 sbt,只需添加到您的 build.sbt
文件:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.13"
使用 AST
播放 json
让我们读取输入文件:
import play.api.libs.json.Json
object Main extends App {
// first we'll need a inputstream of your json object
// this should be familiar if you know java.
val in = new FileInputStream(args(0))
// now we'll let play-json parse it
val json = Json.parse(in)
}
让我们从 AST 中提取一些字段:
val code = (json \ "code").as[String]
val uniqueID = (json \ "unique ID").as[UUID]
for {
JsObject(nameMap) ← (json \ "names").as[Seq[JsObject]]
(name, userMeta) ← nameMap // nameMap is a Map[String, JsValue]
} println(s"User $name has the favorite color ${(userMeta \ "fav-colour").as[String]}")
使用反序列化
正如我刚才所描述的,我们可能会创建代表您的结构的案例 classes:
case class InputFile(code: String, `unique ID`: UUID, count: String, names: Seq[Map[String, UserData]])
case class UserData(name: String, properties: Seq[String], `fav-colour`: String)
此外,您还需要定义一个隐式的 Format
,例如在每个案例的伴生对象中 class。您可以使用为您导出它的 Json.format
宏,而不是手动编写它:
object UserData {
implicit val format: OFormat[UserData] = Json.format[UserData]
}
object InputFile {
implicit val format: OFormat[InputFile] = Json.format[InputFile]
}
您现在可以反序列化您的 json 对象:
val argumentData = json.as[InputFile]
我通常更喜欢这种方法,但在您的情况下,json 结构不太适合。一项改进可能是向您的 InputFile
class 添加一个额外的 getter ,这使得访问具有 space 和类似名称的字段更容易:
case class InputFile(code: String, `unique ID`: UUID, count: String, names: Seq[Map[String, String]]) {
// this method is nicer to use
def uniqueId = `unique ID`
}
我正在编写一个小的 scala 练习代码,我的输入将成为时尚 -
{
"code": "",
"unique ID": "",
"count": "",
"names": [
{
"Matt": {
"name": "Matt",
"properties": [
"a",
"b",
"c"
],
"fav-colour": "red"
},
"jack": {
"name": "jack",
"properties": [
"a",
"b"
],
"fav-colour": "blue"
}
}
]
}
我会将此文件作为命令行参数传递。 我想知道如何接受输入文件解析 json 并在我的代码中使用 json 键?
您可以使用 json 库,例如 play-json 来解析 json 内容。
您可以对 json AST 进行操作,或者您可以编写与 json 文件具有相同结构的 case classes 并让它们被解析。
您可以找到库的文档 here。
您首先必须将 playjson 作为依赖项添加到您的项目中。如果您使用的是 sbt,只需添加到您的 build.sbt
文件:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.13"
使用 AST
播放 json让我们读取输入文件:
import play.api.libs.json.Json
object Main extends App {
// first we'll need a inputstream of your json object
// this should be familiar if you know java.
val in = new FileInputStream(args(0))
// now we'll let play-json parse it
val json = Json.parse(in)
}
让我们从 AST 中提取一些字段:
val code = (json \ "code").as[String]
val uniqueID = (json \ "unique ID").as[UUID]
for {
JsObject(nameMap) ← (json \ "names").as[Seq[JsObject]]
(name, userMeta) ← nameMap // nameMap is a Map[String, JsValue]
} println(s"User $name has the favorite color ${(userMeta \ "fav-colour").as[String]}")
使用反序列化
正如我刚才所描述的,我们可能会创建代表您的结构的案例 classes:
case class InputFile(code: String, `unique ID`: UUID, count: String, names: Seq[Map[String, UserData]])
case class UserData(name: String, properties: Seq[String], `fav-colour`: String)
此外,您还需要定义一个隐式的 Format
,例如在每个案例的伴生对象中 class。您可以使用为您导出它的 Json.format
宏,而不是手动编写它:
object UserData {
implicit val format: OFormat[UserData] = Json.format[UserData]
}
object InputFile {
implicit val format: OFormat[InputFile] = Json.format[InputFile]
}
您现在可以反序列化您的 json 对象:
val argumentData = json.as[InputFile]
我通常更喜欢这种方法,但在您的情况下,json 结构不太适合。一项改进可能是向您的 InputFile
class 添加一个额外的 getter ,这使得访问具有 space 和类似名称的字段更容易:
case class InputFile(code: String, `unique ID`: UUID, count: String, names: Seq[Map[String, String]]) {
// this method is nicer to use
def uniqueId = `unique ID`
}