Reputation: 26441
I'm having following String:
[{"name":"Bob","age":"23"},{"name":"Alice","age":"31"},...]
and I would like to transform it into an array:
["Bob", "Alice", ...]
How I can achieve that?
Upvotes: 0
Views: 2268
Reputation: 14806
That's rather easy. Just convert a JSON array to Scala collection and map names. E.g. using Circe:
import io.circe._
import io.circe.generic.auto._
case class Person(name: String, age: Int)
val peopleAsJson = """[{"name":"Bob","age":"23"},{"name":"Alice","age":"31"}]"""
val personNames = decode[Vector[Person]](peopleAsJson).getOrElse(throw new Exception("Encoding failed")).map(_.name).asJson.noSpaces
Or you can just do it via JavaScript if that's an option.
Upvotes: 1
Reputation: 3474
One way would be to use Scala's in-built JSON parser. Something like this would work (though it could probably be refactored):
import scala.util.parsing.json._
JSON.parseFull("""[{"name":"Bob","age":"23"},{"name":"Alice","age":"31"}]""") match {
// get the head and tail of the List and check the head's type
case Some((m: Map[_, _]) :: l) =>
m.keys.headOption match {
// match type of keys - maybe unnecessary but better safe than sorry
case Some(_: String) =>
// add the head back to the tail, get name values
println((m +: l).asInstanceOf[List[Map[String, Any]]]
.map(_.getOrElse("name", "")))
case _ => ()
}
case _ => ()
}
In REPL:
scala> import scala.util.parsing.json._
import scala.util.parsing.json._
scala> JSON.parseFull("""[{"name":"Bob","age":"23"},{"name":"Alice","age":"31"}]""") match {
| case Some((m: Map[_, _]) :: l) =>
| m.keys.headOption match {
| case Some(_: String) => println((m +: l).asInstanceOf[List[Map[String, Any]]].map(_.getOrElse("name", "")))
| case _ => ()
| }
| case _ => ()
| }
List(Bob, Alice)
res0: Any = ()
If you have already validated the structure of the JSON though, you can ignore all of the type validation - this stuff just avoids it freaking out if the types don't match (and is more cumbersome than is ideal due to type erasure).
It would be much easier if you were using Scala Play and case classes (which again can probably be refactored):
import play.api.libs.json.{Json, OFormat}
case class Person(name: String, age: String)
object Person {
implicit val format: OFormat[Person] = Json.format[Person]
}
Json.parse("""[{"name":"Bob","age":"23"},{"name":"Alice","age":"31"}]""")
.asOpt[List[Person]] match {
case Some(people) => println(people.map(_.name)) // List(Bob, Alice)
case _ => println(Seq())
}
Upvotes: 0