Scala 使用Argonaut镜头从JSON对象的JSON数组中提取值

Scala 使用Argonaut镜头从JSON对象的JSON数组中提取值,scala,scalaz,lenses,argonaut,Scala,Scalaz,Lenses,Argonaut,这是我第一次使用argonauts,对镜头只有一点了解(足够应付)。我花了一段时间试图自己解决这个问题,但一无所获 我正试图构建一个镜头,从一些JSON中获取JsonArray(字符串)。我可以到达拥有数组的对象,但不确定从那里做什么 JSON看起来像: 到目前为止,我的镜头是: val hashtagsView = twitterEntitiesView >=> jsonObjectPL("hashtags") >=> jArrayPL 我不确定那jArrayPL是

这是我第一次使用argonauts,对镜头只有一点了解(足够应付)。我花了一段时间试图自己解决这个问题,但一无所获

我正试图构建一个镜头,从一些JSON中获取JsonArray(字符串)。我可以到达拥有数组的对象,但不确定从那里做什么

JSON看起来像:

到目前为止,我的镜头是:

val hashtagsView = twitterEntitiesView >=> jsonObjectPL("hashtags") >=> jArrayPL
我不确定那
jArrayPL
是否正确。我想做的只是从数组中检索文本

总而言之,有谁能帮我找出如何构造一个镜头来查看hashtags,然后对数组中的每个元素查看文本,最后得到一个值作为a
JsonArray

更新:

在Travis的帮助下,我编译了以下代码:

import argonaut._, Argonaut._
import monocle.std.list._, monocle.function.Each.each, monocle.function.Index.index
import scalaz._, Scalaz._

val \/-(json) = Parse.parse(rawJSON)
val lens = jObjectPrism
          .composeOptional(index("hashtags"))
          .composePrism(jArrayPrism)
          .composeTraversal(each[List[Json], Json])
          .composePrism(jObjectPrism)
          .composeOptional(index("text"))
          .composePrism(jStringPrism)

println(lens.getAll(json))
不幸的是,我得到了一个运行时错误:
scalaz.scalaz$.ToEitherOps(Ljava/lang/Object;)Lscalaz/syntax/EitherOps
val\/-(json)=Parse.Parse(rawJSON)


提前谢谢

您愿意使用Argonaut提供的镜片而不是Scalaz镜片吗?如果是这样,使用遍历就更好了:

import argonaut._, Argonaut._
import monocle.function.{ each, index }, monocle.std.list._
import scalaz._, Scalaz._

val doc = """{
  "hashtags": [
    { "indices": [0, 3], "text": "foo" },
    { "indices": [3, 6], "text": "bar" }
  ]
}"""

val \/-(json) = Parse.parse(doc)

val lens = jObjectPrism
  .composeOptional(index("hashtags"))
  .composePrism(jArrayPrism)
  .composeTraversal(each[List[Json], Json])
  .composePrism(jObjectPrism)
  .composeOptional(index("text"))
  .composePrism(jStringPrism)
然后:

scala> lens.getAll(json)
res0: List[argonaut.Argonaut.JsonString] = List(foo, bar)

scala> lens.modify(_ + " (new)")(json).spaces2
res1: String =
{
  "hashtags" : [
    {
      "indices" : [
        0,
        3
      ],
      "text" : "foo (new)"
    },
    {
      "indices" : [
        3,
        6
      ],
      "text" : "bar (new)"
    }
  ]
}

等等。您可以使用Scalaz镜头执行类似操作,但这需要更多的工作。

如果您只想提取字段:

import argonaut._, Argonaut._
import scalaz._, Scalaz._

val doc = """{
  "hashtags": [
    { "indices": [0, 3], "text": "foo" },
    { "indices": [3, 6], "text": "bar" }
  ]
}"""

val \/-(json) = Parse.parse(doc)
val lense = jObjectPL
val hashtags = (lense >=> jsonObjectPL("hashtags") >=> jArrayPL).get(json)

hashtags.get.foreach(i => (lense >=> jsonObjectPL("indices") ).get(i).get.println )
hashtags.get.foreach(i => (lense >=> jsonObjectPL("text") ).get(i).get.println )
…或者更好

val ind = ((v:Json) =>(lense >=> jsonObjectPL("indices") ).get(v).get)
val text = ((v:Json) =>(lense >=> jsonObjectPL("text") ).get(v).get)

hashtags.get.foreach(i => (ind(i), text(i)).println )

谢谢你的回答@Travis。我能否澄清这是伪代码还是应该可以运行?我问这个问题的原因是我无法让它自己运行。下面是我得到的错误信息:我使用的是Monocle版本1.2.0、Scalaz版本7.0.6和Argonaut版本6.0.4。希望没有依赖性问题。@FintahH这是一个真正的REPL会话,但是使用Argonaut 6.1,它使用了不同的单眼镜版本和稍微不同的包安排。我现在不在电脑旁,但可以稍后提供6.0.4版的正确进口。@FintanH哦,对不起,我错了。6.0.4版中根本没有单眼镜头。对了!因此,我刚刚更新到6.1,因为我在探索示例时看到了更新。我现在无法使用的唯一部分是
每个
索引
函数,因为它们说它们不在该包中。我们能够编译,但出现了运行时错误。更新了帖子。