json - 从 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"
}
}
}
}
}
}
}
解决方案
推荐阅读
- c# - 如何在 .Net Core 3.0 中获得对 MS Access 的引用?
- powershell - 尝试在 PowerShell 中发出 curl POST 命令
- python - Django:为什么在虚拟环境中找不到包?
- c# - 使用 CAP 时如何设置 RabbitMQ 队列前缀
- c# - 为什么在实例化类时使用 using()?
- asp.net-core - asp.net Core Identity 中 SubDomain 的 cookie
- javascript - 我应该使用 console.error() 还是 throw new Error()
- intellij-idea - 无法查找 JNDI 名称 [jdbc/EPAR]
- python-3.x - 如何在 kivy 的 2 个类之间传递变量?
- bpf - 无法将字符串与 eBPF 进行比较