从json-Clojure中的文本文件创建树

从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"

我有一个文本文件,每行包含一个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":"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"))`
    
  • 如何将JSON转换为Clojure数据

    (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
    ,因为此处不支持它。相反,我建议对树进行后序遍历,以创建一个更自然的替代表示。请参阅链接到答案中的链接。