scala - Mapping over a JSON array with Argonaut -
i'm having hard time slogging through argonaut documentation, figured i'd ask simple example.
val input = """{"a":[{"b":4},{"b":5}]}""" val output = ??? // desired value: list(4, 5)
i can cursor down array:
parse.parse(input).map((jobjectpl >=> jsonobjectpl("a") >=> jarraypl)(_)) // scalaz.\/[string,option[scalaz.indexedstore[argonaut.argonaut.jsonarray, // argonaut.argonaut.jsonarray,argonaut.json]]] = // \/-(some(indexedstoret((<function1>,list({"b":4}, {"b":5})))))
but what? on right track? should using cursors this?
edit - here's progress, guess. i've written decoder list:
parse.parse("""[{"b": 4}, {"b": 5}]""") .map(_.as(ilistdecodejson(decodejson(_.downfield("b").as[int])))) // scalaz.\/[string,argonaut.decoderesult[scalaz.ilist[int]]] = // \/-(decoderesult(\/-([4,5])))
edit - starting put together...
parse.parse(input).map(_.as[hcursor].flatmap(_.downfield("a").as( ilistdecodejson(decodejson(_.downfield("b").as[int]))))) // scalaz.\/[string,argonaut.decoderesult[scalaz.ilist[int]]] = // \/-(decoderesult(\/-([4,5])))
edit - guess best solution far is:
parse.parse(input).map(_.as( decodejson(_.downfield("a").as( ilistdecodejson(decodejson(_.downfield("b").as[int])).map(_.tolist) )) ))
feels bit verbose, though.
you can pretty nicely new-ish monocle support in argonaut (i'm using argonaut master here, since 6.1 milestones still on monocle 0.5):
import argonaut._, argonaut._ import scalaz._, scalaz._ import monocle._, monocle._ val lens = parse.parseoptional ^<-? jobjectprism ^|-? index("a") ^<-? jarrayprism ^|->> each ^<-? jobjectprism ^|-? index("b") ^<-? jintprism
and then:
scala> lens.getall("""{"a":[{"b":4},{"b":5}]}""") res0: scalaz.ilist[int] = [4,5]
the operators horrible @ first, used them, , composed pieces read pretty naturally. , of course since lens there kinds of operations can use in addition getall
.
Comments
Post a Comment