简体   繁体   English

如何在Clojure中向哈希映射图添加新节点?

[英]How to Add a New Node to Hash-Map Graph in Clojure?

I have the following array-map created in Clojure. 我在Clojure中创建了以下数组映射。

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

How do i go about adding elements into this, running the following code 如何运行以下代码,向其中添加元素

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

gives me 给我

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

and running 并运行

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

gives me the following error message. 给我以下错误信息。 how do i add elements into the children sections on the array-map 如何将元素添加到数组映射的子级部分

Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Associative,

Let's assign our tree to t : 让我们将树分配给t

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

To add a new child note: 要添加新的子注释:

(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]}

Of course this is not exactly what we want. 当然,这并不是我们想要的。

(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 []}]}

Building trees is now a matter of combining make-node & add-child . 现在,构建树是结合make-nodeadd-child

If you want to work on deep hierarchies, I suggest using a zipper . 如果您想处理较深的层次结构,建议您使用拉链

for adding a new node, the basic idea is general. 对于添加新节点,基本思想是一般性的。 anyway, the prog needs to know where to place the new child. 无论如何,编要知道将新孩子放在哪里。 when arriving the parent node of the new child, the prog appends the new child to it. 当到达新子节点的父节点时,编会将新子节点追加到该子节点。 the rest problem is how to traverse a graph in clojure. 剩下的问题是如何在Clojure中遍历图。 clojure.walk module is for that purpose. clojure.walk模块就是用于此目的。

one implementation of adding a new node to your graph is as follows: 向图中添加新节点的一种实现如下:

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

testing: 测试:

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 []}]}]}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM