Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用argonaut/circe解码json数组中的单个对象字段_Json_Argonaut - Fatal编程技术网

使用argonaut/circe解码json数组中的单个对象字段

使用argonaut/circe解码json数组中的单个对象字段,json,argonaut,Json,Argonaut,假设我有这样的想法 { "sha": "some sha", "parents": [{ "url": "some url", "sha": "some parent sha" }] } 还有这样的案例课 case class Commit(sha: String, parentShas: List[String]) 在播放json时,我可以这样写: val commitReads: Reads[Commit] = ( (JsPath \ "sha").rea

假设我有这样的想法

{
  "sha": "some sha",
  "parents": [{
    "url": "some url",
    "sha": "some parent sha"
  }]
}
还有这样的案例课

case class Commit(sha: String, parentShas: List[String])
在播放json时,我可以这样写:

val commitReads: Reads[Commit] = (
  (JsPath \ "sha").read[String] and
  (JsPath \ "parents" \\ "sha").read[List[String]]
)(Commit.apply _)

我正在寻找一种仅解码argonaut/circe中“parent”的“sha”的等效方法,但我没有找到任何方法。“HCursor/ACursor”有下行数组,但从那以后我不知道该怎么办。提前非常感谢

circe和Argonaut都不跟踪在JSON对象中读取了哪些字段,因此您可以忽略额外的
“url”
字段(就像在游戏中一样)。更棘手的部分是找到与Play的
\\
等价的东西,circe目前还没有,尽管你已经说服我我们需要添加它

首先,如果您有一个单独的SHA类型,这是相对容易的:

import io.circe.Decoder

val doc = """
{
  "sha": "some sha",
  "parents": [{
    "url": "some url",
    "sha": "some parent sha"
  }]
}
"""

case class Sha(value: String)

object Sha {
  implicit val decodeSha: Decoder[Sha] = Decoder.instance(_.get[String]("sha")).map(Sha(_))
}

case class Commit(sha: Sha, parentShas: List[Sha])

object Commit {
  implicit val decodeCommit: Decoder[Commit] = for {
    sha <- Decoder[Sha]
    parents <- Decoder.instance(_.get[List[Sha]]("parents"))
  } yield Commit(sha, parents)
}
然后:

scala> import io.circe.jawn._
import io.circe.jawn._

scala> decode[Commit](doc)
res0: cats.data.Xor[io.circe.Error,Commit] = Right(Commit(Sha(some sha),List(Sha(some parent sha))))
但这并不是一个真正的答案,因为我不会要求你改变你的模型实际答案就没那么有趣了:

case class Commit(sha: String, parentShas: List[String])

object Commit {
  val extractSha: Decoder[String] = Decoder.instance(_.get[String]("sha"))

  implicit val decodeCommit: Decoder[Commit] = for {
    sha <- extractSha
    parents <- Decoder.instance(c =>
      c.get("parents")(Decoder.decodeCanBuildFrom[String, List](extractSha, implicitly))
    )
  } yield Commit(sha, parents)
}
case类提交(sha:String,parentShas:List[String])
对象提交{
val-extractSha:Decoder[String]=Decoder.instance(u.get[String](“sha”))
隐式val decodeCommit:Decoder[Commit]=for{
沙
case class Commit(sha: String, parentShas: List[String])

object Commit {
  val extractSha: Decoder[String] = Decoder.instance(_.get[String]("sha"))

  implicit val decodeCommit: Decoder[Commit] = for {
    sha <- extractSha
    parents <- Decoder.instance(c =>
      c.get("parents")(Decoder.decodeCanBuildFrom[String, List](extractSha, implicitly))
    )
  } yield Commit(sha, parents)
}