如何在Clojure中向Hash-Map图形添加新节点?

时间:2015-04-27 14:29:23

标签: vector clojure array-map

我在Clojure中创建了以下数组映射。

{:node 7, :children [{:node 8, :children []} {:node 6, :children []} {:node 23, :children {}} {:node 43, :children []}]}

如何在此添加元素, 运行以下代码

(def tree (assoc-in tree [:node] 12))

给了我

{:node 12, :children [{:node 8, :children []} {:node 6, :children []} {:node 10, :children {}} {:node 13, :children []} {:node 28, :children []}]}`

并正在运行

(def tree (assoc-in tree [:node :children] 12))

给我以下错误消息。如何在array-map

的子节中添加元素
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Associative,

2 个答案:

答案 0 :(得分:2)

让我们将树分配给t

(def t {:node 7, 
        :children [{:node 8, :children []} 
                   {:node 6, :children []} 
                   {:node 23, :children []} 
                   {:node 43, :children []}]})

添加新的儿童便笺:

(defn add-child [tree node]
  (assoc-in tree 
            [:children] 
            (conj (:children tree) node)))

(add-child t :foo)
;; => {:node 7, 
;;     :children [{:node 8, :children []} 
;;                {:node 6, :children []} 
;;                {:node 23, :children []} 
;;                {:node 43, :children []} 
;;                :foo]}

当然这不是我们想要的。

(defn make-node [value children] 
  (let [c (into [] children)] 
    {:node value 
     :children c}))

(make-node 5 nil)
;; => {:node 5, :children []}

(make-node 5 [(make-node 3 nil) (make-node 7 nil)])
;; => {:node 5, 
;;     :children [{:node 3, :children []} 
;;                {:node 7, :children []}]}

现在建立树木是make-node&组合的问题。 add-child

如果您想处理深层次结构,我建议您使用zipper

答案 1 :(得分:1)

添加新节点,基本思路是通用的。无论如何,编程需要知道新孩子的位置。当到达新孩子的父节点时,prog将新孩子附加到它。剩下的问题是如何遍历clojure中的图形。 clojure.walk 模块就是为了这个目的。

向图表添加新节点的一个实现如下:

(defn tree-add
  [root parent-key new-node]
  (clojure.walk/postwalk #(if (= parent-key (:node %))
                            (assoc % :children (conj (:children %) new-node))
                            %)
                         root))

测试:

user> a
{:node 7, :children [{:node 8, :children []}]}
user> (tree-add a 7 {:node 99 :children []})
{:node 7, :children [{:node 8, :children []} {:node 99, :children []}]}
user> (tree-add a 8 {:node 199 :children []})
{:node 7, :children [{:node 8, :children [{:node 199, :children []}]}]}