从json-Clojure中的文本文件创建树
我有一个文本文件,每行包含一个json值。我的档案如下:从json-Clojure中的文本文件创建树,json,clojure,tree,Json,Clojure,Tree,我有一个文本文件,每行包含一个json值。我的档案如下: {"id":"a","family":"root","parent":nil,"value":"valueofa"} {"id":"b1","family":"b","parent":"a","value":"valueofb1"} {"id":"c1","family":"c","parent":"b1","value":"valueofc1"} {"id":"c2","family":"c","parent":"b1","value"
{"id":"a","family":"root","parent":nil,"value":"valueofa"}
{"id":"b1","family":"b","parent":"a","value":"valueofb1"}
{"id":"c1","family":"c","parent":"b1","value":"valueofc1"}
{"id":"c2","family":"c","parent":"b1","value":"valueofc2"}
{"id":"b2","family":"b","parent":"root","value":"valueofb2"}
{"id":"d1","family":"d","parent":"b1","value":"valueofd1"}
在上面给出的json中,我们认为family属性表示一个层次结构,我们将“root”作为根,“b”作为“root”的子级,“c”作为“b”的子级,“d”也将是“b”的子级
其思想是遍历文件,并将正在读取的节点添加到树中的适当位置。一种方法是将这些条目读入“映射”,然后将该映射用于任何树操作。对于任何复杂的树操作,我不确定这将如何工作。很有可能,基于某个特定的需求,我可能不得不将一个子项从现有父项中分离出来,并将其附加到另一个父项。显然Clojure拉链应该在这方面有所帮助,但我对拉链中节点的层次结构是如何工作的感到有点困惑
如果有人能给我指出正确的方向,那就太好了。这是几个问题,可能太宽泛了,但这里有一个样本
(def file-contents (slurp "foo.txt"))`
(require '[cheshire.core :refer [parse-string]])`
(def data (map #(parse-string % true)
(clojure.string/split file-contents #"\n")))
(require '[clojure.zip :as z])
(defn create-zipper [s]
(let [g (group-by :parent s)]
(z/zipper g #(map :id (g %)) nil (-> nil g first :id))))
(def t (create-zipper data))
看user=> (-> t z/node)
"a"
user=> (-> t z/children)
("b1")
user=> (-> t z/down z/node)
"b1"
user=> (-> t z/down z/children)
("c1" "c2" "d1")
user=> (-> t z/down z/down z/rightmost z/node)
"d1"
您可以使用获取数据结构非常感谢这个分解,我有一个关于zippers的问题,根据文档,zippers包含4个参数:branch?,children,make node和root。如果您能够详细说明g如何映射到分支?,子节点是#(map:id(g%)),make node是nil,root是(->nil g first:id),那就太好了。作为clojure的新手,这似乎有点深奥。在clojure中,映射可以充当从键到值的函数。因此,使用
g
作为branch?
就是询问在parent
-hood的关系中是否存在任何值(子项)。关键字也可以作为映射上的函数,因此如果我们将:id
映射到这些子项上,我们只是提取它们的:id
字段。Make节点为nil
,因为此处不支持它。相反,我建议对树进行后序遍历,以创建一个更自然的替代表示。请参阅链接到答案中的链接。