首页 > 解决方案 > 从 JSON 树中的一组多态节点创建 Scalaz 树的建议

问题描述

我以前使用 C++ 和 Antlr 等工具来读取 DSL 并将其转换为 AST/符号表,然后使用树遍历器创建对象模型,然后对其进行详细说明,然后将生成的数据结构生成为另一种语言.

我知道如何以多种不同的方式遍历/转换 Scala 树和图形。我正在为如何创建一个 JSON 解析器而苦苦挣扎,该解析器将以一种优雅的方式创建一棵树。

可以用Circe解析JSON,然后读取Circe数据结构,在遍历的过程中检查每个节点的类型,创建对应的case类对象。不知道有没有更简单的方法。

使用 JSON 描述具有多态节点的树的高级规范如下 Scala 库可以将 JSON 转换为 Scala 树?

将编辑树并添加、删除和移动节点以创建新的不可变数据结构。

我看过 Scalaz,但它可能不合适,因为有不同的节点类型,我不确定如何直接从 JSON 转到 Scalaz 树。

https://scalaz.github.io/scalaz/scalaz-2.9.1-6.0.4/doc.sxr/scalaz/Tree.scala.html#40955

示例: https ://scalaz.github.io/scalaz/scalaz-2.9.1-6.0.4/doc.sxr/scalaz/example/ExampleTree.scala.html

object ExampleTree {
  def main(args: Array[String]) = run

  import Scalaz._

  def run {
    val tree: Tree[Int] =
    1.node(
      2.leaf,
      3.node(
        4.leaf))

此链接以功能方式遍历树具有使用相同节点类型构造的树的示例。见下文。

package main

import scala.collection.mutable.ListBuffer

sealed trait Tree[Node] {

  val node: Node

  val parent: Option[Tree[Node]]

  val children: ListBuffer[Tree[Node]]

  def add(n: Node): Tree[Node]

  def size: Int

  def getOpt(p: (Node) => Boolean): Option[Tree[Node]]

  override def toString = {
    s"""[$node${if (children.isEmpty) "" else s", Children: $children"}]"""
  }
}

case class ConcreteTree(override val node: Int) extends Tree[Int] {

  override val children = ListBuffer[Tree[Int]]()

  override val parent: Option[Tree[Int]] = None

  override def add(n: Int): ConcreteTree = {
    val newNode = new ConcreteTree(n) {override val parent: Option[Tree[Int]] = Some(this)}
    children += newNode
    newNode
  }
}

我要问的是一种将多态 JSON 转换为树结构的 Scala 方法。

树中的每个节点类型都有一个对应的案例类。JSON 需要被解析,类型匹配和用于 JSON 类型的正确 case 类。

如果您觉得这个问题在某种程度上违反了 StackOverflow 的政策,而不是给它一个减分,也许您可​​以发表评论并提出有关如何更改问题以符合 StackOverflow 规则的建议。

示例 JSON:

{
  "root": {
    "Container": {
      "attributes": [],
      "children": {
        "Container": {
          "attributes": [],
          "children": {
            "Container": {
              "attributes": [],
              "children": {
                "circle": {
                  "fill": "blue",
                  "diameter": "4"
                }
              }
            },
            "square": {
              "name": "Y",
              "color": "red",
              "length": "10",
              "width": "4"
            }
          }
        }
      }
    }
  }
}

标签: jsonscalatreescalaz

解决方案


推荐阅读