使用 Argonaut 透镜从 JSON 个包含 JSON 个对象的数组中提取值
Extracting values from JSON Array of JSON Objects using Argonaut Lenses
第一次用argonauts,对镜头的了解也很少(勉强过得去)。我花了一段时间试图自己找出问题,但一无所获。
我正在尝试构建一个镜头以从某些 JSON 获取 JsonArray(字符串)。我可以到达具有数组的对象,但不确定从那里做什么。
JSON 看起来像:
到目前为止我的镜头是这样的:
val hashtagsView = twitterEntitiesView >=> jsonObjectPL("hashtags") >=> jArrayPL
我也不确定 jArrayPL
是否正确。我想做的只是从数组中检索文本。
所以总结一下,谁能帮我找出如何构建一个镜头来查看主题标签,然后为数组的每个元素查看文本,最后得到一个值作为 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 提供的 Monocle 镜头来代替 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 )
第一次用argonauts,对镜头的了解也很少(勉强过得去)。我花了一段时间试图自己找出问题,但一无所获。
我正在尝试构建一个镜头以从某些 JSON 获取 JsonArray(字符串)。我可以到达具有数组的对象,但不确定从那里做什么。
JSON 看起来像:
到目前为止我的镜头是这样的:
val hashtagsView = twitterEntitiesView >=> jsonObjectPL("hashtags") >=> jArrayPL
我也不确定 jArrayPL
是否正确。我想做的只是从数组中检索文本。
所以总结一下,谁能帮我找出如何构建一个镜头来查看主题标签,然后为数组的每个元素查看文本,最后得到一个值作为 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 提供的 Monocle 镜头来代替 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 )