我正在编写一个小的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键吗?
答案 0 :(得分:3)
您可以使用play-json之类的json库来解析json内容。
您可以对JSON AST进行操作,也可以编写与json文件具有相同结构的case类,然后对其进行解析。
您可以找到库here的文档。
您首先必须将playjson作为依赖项添加到您的项目中。如果您使用的是sbt,只需将其添加到build.sbt
文件中:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.13"
让我们阅读输入文件:
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]}")
正如我刚刚描述的,我们可能会创建代表您的结构的案例类:
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
,例如在每个案例类的伴随对象中。不用手工编写,可以使用为您派生它的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
类中添加一个额外的getter,以使使用空格和名称相似的字段更容易访问:
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`
}