在JSON字段的模式匹配中Scala的奇怪行为(json4s框架)

在JSON字段的模式匹配中Scala的奇怪行为(json4s框架),scala,scala-2.10,json4s,Scala,Scala 2.10,Json4s,我正在尝试遍历JSON并提取字段中对象类型的信息: import org.json4s._ import org.json4s.JsonAST.{JArray, JString, JObject, JInt, JBool, JDouble} import org.json4s.JsonDSL._ import org.json4s.native.JsonMethods._ def guessTypes(example: JValue): JObject = example match { ca

我正在尝试遍历JSON并提取字段中对象类型的信息:

import org.json4s._
import org.json4s.JsonAST.{JArray, JString, JObject, JInt, JBool, JDouble}
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._

def guessTypes(example: JValue): JObject = example match {
case JObject(lst) => JObject(lst.map {
  case (f, JObject(nested)) => JField(f, ("type" -> "object") ~ ("properties" -> guessTypes(nested)))
  case (f, JString(s)) => JField(f, "type" -> "string")
  case (f, JInt(num)) => JField(f, "type" -> "integer")
  case (f, JDouble(double)) => JField(f, "type" -> "double")
  case (f, JBool(b)) => JField(f, "type" -> "bool")
  case (f, JArray(jarray: List[JInt])) => JField(f, ("type" -> "array") ~ ("items" -> "integer"))
  case (f, JArray(jarray: List[JString])) => JField(f, ("type" -> "array") ~ ("items" -> "string"))
  case (f, JArray(jarray: List[JObject])) => JField(f, ("type" -> "array") ~ ("items" -> "object")) ~ ("properties" -> jarray.map{ x => guessTypes(x)}))
})}
在下列情况下:

def example = """
    |{
    |  "partners_data": [
    |    {
    |      "info": {
    |        "label": "partner45"
    |      },
    |      "partner_id": "partner45",
    |      "data": {
    |        "field": 24
    |      }
    |    }
    |  ],
    |  "name": "*****(",
    |  "location": [
    |    1,
    |    2
    |  ],
    |  "is_mapped": false
    |}
  """.stripMargin
结果如下:

{“数据”:{“类型”:“数组”,“项”:“对象”},名称”:{“类型”:“字符串”},位置”:{“类型”:“数组”,“项”:“对象”},映射为:{“类型”:“bool”}

这不是合适的结果,因为对于“location”中的键“items”,需要值“integer”

看起来Scala除了JArrays中的JValue之外,无法区分其他任何东西。如果我替换

案例(f,JArray(JArray:List[JInt]))

通过最后一个字符串,对于“位置”中的键“项”,将获得“对象”,但对于其他字段,值将是错误的


我如何绕过scala模式匹配和json4s框架的这一特性?

后三种模式本质上是相同的,因为它们在JVM上是相同的

由于JSON数组可以包含多个(Scala/Java/…)类型,因此很难匹配列表中元素的类型

只能检查数组的第一项:

case (f, JArray(JString(_) :: tail)) => 
  JField(f, ("type" -> "array") ~ ("items" -> "string"))
case (f, JArray(jarray @ JObject(_) :: tail)) => 
  JField(f, ("type" -> "array") ~ ("items" -> "object") ~ ("properties" -> jarray.map(guessTypes)))
或者检查数组中的每个项目:

case (f, JArray(list : List[JValue])) if list forall { case JInt(_) => true; case _ => false } => 
  JField(f, ("type" -> "array") ~ ("items" -> "integer"))

您使用的是什么版本的Json4s?使用
“org.json4s”%%“json4s原生”%%“3.2.2”
时,我得到了正确的类型。我使用的是
“org.json4s”%%“json4s原生”%%“3.2.11”
。在我们的例子中,没有机会使用早期版本的json4s。