Разобрать вложенную json структуру - PullRequest
0 голосов
/ 07 января 2020

У меня есть вложенный файл json, как показано ниже

{
    "Message No": 1.0,
    "abc": {
        "action": {
            "ab1": false,
            "ab2": false
        },
        "val": "Global"
    },

    "tyu": {
        "lmp": [{
            "Currency": "USD",
            "Amount": "32401.32"
        }]
    },

    "Payments": {
        "Array": ["Hi", "There"],
        "Details": [{
            "Date": "2019-04-11"
        }]
    }
}

Я нашел фрагмент кода от Google, который преобразует его в простую пару ключ-значение. Код похож на ниже

def Simply(m: Map[String, Any], tree: List[String] = List()) : Iterable[(String, Any)] = m.flatten
  {
    case (k: String, v: Map[String, Any] @unchecked) => Simply(v, tree :+ k)
    case (k: String, v: List[Map[String, Any]] @unchecked) => v.flatten(Simply(_, tree :+ k))
    case (k: String, v: Any) => List((tree :+ k.toString).mkString("_") ->v)
    case (k,null) => List((tree :+ k.toString).mkString("_") ->"null")

  }

Код работает нормально, но он не может обработать элемент Array в json

"Array": ["Hi", "There"],

Я пытался поставить дополнительное условие, например

case (k: String, v: List[String]) => List((tree :+ k.toString).mkString("_") ->v.mkString(","))

, но тогда это условие блокирует приведенный ниже случай в простой функции

case (k: String, v: List[Map[String, Any]] @unchecked) => v.flatten(Simply(_, tree :+ k))

Пожалуйста, помогите мне понять, если я помещаю условие в неправильное место или любое изменение кода, которое мне нужно сделать

Ожидаемый вывод

(tyu_lmp_Amount,32401.32)
(abc_action_ab1,false)
(Message No,1.0)
(abc_action_ab2,false)
(tyu_lmp_Currency,USD)
(Payments_Details_Date,2019-04-11)
(Payments_Array,{Hi, There})
(abc_val,Global)

1 Ответ

0 голосов
/ 08 января 2020

Я надеюсь, что это то, что вы хотите:

package advanced

import org.json4s._
import org.json4s.jackson.JsonMethods._

object JsonTest extends App {

  val s =
    """
      |{
      |    "Message No": 1.0,
      |    "abc": {
      |        "action": {
      |            "ab1": false,
      |            "ab2": false
      |        },
      |        "val": "Global"
      |    },
      |
      |    "tyu": {
      |        "lmp": [{
      |            "Currency": "USD",
      |            "Amount": "32401.32"
      |        }]
      |    },
      |
      |    "Payments": {
      |        "Array": ["Hi", "There"],
      |        "Details": [{
      |            "Date": "2019-04-11"
      |        }]
      |    }
      |}
      |""".stripMargin


  def jsonStrToMap(jsonStr: String): Map[String, Any] = {
    implicit val formats = org.json4s.DefaultFormats

    parse(jsonStr).extract[Map[String, Any]]
  }

  def Simply(m: Map[String, Any], tree: List[String] = List()) : Iterable[(String, Any)] = m.flatMap {
      case (k: String, v: Map[String, Any]) => Simply(v, tree :+ k)
      case (k: String, v: List[Any]) if v.headOption.exists(_.isInstanceOf[Map[String, Any]]) => v.flatMap{ subNode =>
        Simply(subNode.asInstanceOf[Map[String, Any]], tree :+ k)
      }
      case (k: String, v: List[String]) => List((tree :+ k.toString).mkString("_") -> v.mkString(","))
      case (k: String, v: Any) => List((tree :+ k.toString).mkString("_") ->v)
      case (k,null) => List((tree :+ k.toString).mkString("_") ->"null")

    }

  val map = jsonStrToMap(s)
  println(Simply(jsonStrToMap(s)))

  //
  // Map(tyu_lmp_Amount -> 32401.32, abc_action_ab1 -> false, Message No -> 1.0, abc_action_ab2 -> false, tyu_lmp_Currency -> USD, Payments_Details_Date -> 2019-04-11, Payments_Array -> Hi,There, abc_val -> Global)
  //
}

сопоставление с шаблоном на [Any] попытается привести его к любому типу в случаях сопоставления с шаблоном, так что v: List[String] поглощает любой подузел, который является список объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...