Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.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
使用json4s在Scala中映射任意嵌套JSON_Scala_Json4s - Fatal编程技术网

使用json4s在Scala中映射任意嵌套JSON

使用json4s在Scala中映射任意嵌套JSON,scala,json4s,Scala,Json4s,我在Scala中使用json4s。现在,考虑到以下JSON: { 'k1': [ {"a" : "hello1", "b": "city1" }, {"a" : "hello2", "b": "city2" }, {"a" : "hello2", "b": "city2" } ], 'k2': [ {"a" : "hello1", "b": "city1" }, {"a" : "hello2", "b": "city2" }, {"a" : "hello2", "

我在Scala中使用json4s。现在,考虑到以下JSON:

{
 'k1': [
  {"a" : "hello1", "b": "city1" },
  {"a" : "hello2", "b": "city2" },
  {"a" : "hello2", "b": "city2" } 
 ],
 'k2': [
  {"a" : "hello1", "b": "city1" },
  {"a" : "hello2", "b": "city2" },
  {"a" : "hello2", "b": "city2" } 
 ]
}
在Scala中将其转换为一级地图的最短方法是什么:

Map(
"k1.$[0].a" => "hello1",
"k1.$[0].b" => "city1",
"k1.$[1].a" => "hello2",
"k1.$[1].b" => "city2",
"k1.$[2].a" => "hello2",
"k1.$[2].b" => "city2",
"k2.$[0].a" => "hello1",
"k2.$[0].b" => "city1",
"k2.$[1].a" => "hello2",
"k2.$[1].b" => "city2",
"k2.$[2].a" => "hello2",
"k2.$[2].b" => "city2"
)
请注意,顶级JSON始终是一个对象,而不是数组,即
{}
[]
。此外,它可以嵌套在没有预先知道限制的深处

EDIT1

好的,这就是我目前正在做的:

import org.json4s._
import org.json4s.native.JsonMethods._

object Experiments {
  def toMap(json: JValue, prefix: String = ""): Map[String, Any] = {
    json match {
      case obj: JObject =>
        obj.values flatMap {
          case (k, v) =>
            toMap(v.asInstanceOf[JValue], prefix + s".$k")
        }
      case arr: JArray =>
        val returnValues = arr.values.zipWithIndex flatMap {
          case (v, index) =>
            toMap(v.asInstanceOf[JValue], prefix + s".$$[$index]")
        }
        returnValues.toMap
      case value: JBool =>
        Map(prefix -> value)
      case value: JDecimal =>
        Map(prefix -> value)
      case value: JDouble =>
        Map(prefix -> value)
      case value: JInt =>
        Map(prefix -> value)
      case value: JString =>
        Map(prefix -> value)
      case JNothing | JNull =>
        Map(prefix -> JNull)
    }
  }

  def main(args: Array[String]) {
    val json2 = parse( """ {"a": {"b": "c"}} """)
    print(toMap(json2))
  }
}
它不起作用,我收到以下错误:

Exception in thread "main" java.lang.ClassCastException: scala.collection.immutable.Map$Map1 cannot be cast to org.json4s.JsonAST$JValue
    at Experiments$$anonfun$toMap$1.apply(Experiments.scala:10)
    at Experiments$$anonfun$toMap$1.apply(Experiments.scala:8)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:252)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:252)
    at scala.collection.immutable.Map$Map1.foreach(Map.scala:116)
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:252)
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:104)
    at Experiments$.toMap(Experiments.scala:8)
    at Experiments$.main(Experiments.scala:35)
    at Experiments.main(Experiments.scala)
EDIT2

JSON string:  {"a": {"b": "c"}} 
(/a/b,c)

JSON string: 
    {
      "k1": [ {"a" : "hello1", "b": "city1" }, {"a" : "hello2", "b": "city2" }, {"a" : "hello2", "b": "city2" } ] ,
      "k2": [ {"a" : "hello1", "b": "city1" }, {"a" : "hello2", "b": "city2" }, {"a" : "hello2", "b": "city2" } ]
    }

(/k1/$[2]/a,hello2)
(/k2/$[0]/a,hello1)
(/k1/$[2]/b,city2)
(/k1/$[1]/a,hello2)
(/k2/$[1]/a,hello2)
(/k1/$[1]/b,city2)
(/k2/$[2]/a,hello2)
(/k2/$[0]/b,city1)
(/k1/$[0]/a,hello1)
(/k2/$[1]/b,city2)
(/k2/$[2]/b,city2)
(/k1/$[0]/b,city1)
以下代码适用于我:

import org.json4s._
import org.json4s.native.JsonMethods._

object Experiments {

  def toMap(v: Any, prefix: String = "", separator: String = "/"): Map[String, Any] = {
    v match {
      case m: Map[_, _] =>
        m.flatMap { case (k, v) =>
          toMap(v, prefix + s"$separator$k")
        }
      case list: List[_] =>
        val returnValues = list.zipWithIndex flatMap {
          case (v, index) =>
            toMap(v, prefix + s"$separator$$[$index]")
        }
        returnValues.toMap
      case _ =>
        Map(prefix -> v)
    }
  }

  def main(args: Array[String]) {
    val s1 = """ {"a": {"b": "c"}} """
    val s2 =
      """
    {
      "k1": [ {"a" : "hello1", "b": "city1" }, {"a" : "hello2", "b": "city2" }, {"a" : "hello2", "b": "city2" } ] ,
      "k2": [ {"a" : "hello1", "b": "city1" }, {"a" : "hello2", "b": "city2" }, {"a" : "hello2", "b": "city2" } ]
    }
      """

    for (s <- List(s1, s2)) {
      println(s"JSON string: $s")
      val json2 = parse(s)
      val flatm = toMap(json2.values)
      flatm foreach println
      println()
    }
  }
}