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

时间:2014-07-20 22:40:22

标签: 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":"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拉链应该在这方面提供帮助,但我对拉链节点的层次结构有点困惑。

如果有人能指出我在正确的方向,那将会很棒。

1 个答案:

答案 0 :(得分:4)

这是几个问题,可能过于宽泛,但这是一个抽样。

  1. 如何阅读文件?

    (def file-contents (slurp "foo.txt"))`
    
  2. 如何将JSON转换为Clojure数据?

    (require '[cheshire.core :refer [parse-string]])`
    
    (def data (map #(parse-string % true)
              (clojure.string/split file-contents #"\n")))
    
  3. 如何使用树之类的父引用来处理列表?

    (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))
    

    请参阅how to transform a seq into a tree

  4. 如何使用拉链?

    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"