Clojure:从集合中删除给定节点的函数

Clojure:从集合中删除给定节点的函数,clojure,Clojure,我希望有一个函数可以从包含该节点的集合中删除任何节点(子集合) (def coll {:a ["b" {:c "d" :e ["f" {:g "h"}]}]}) (def node {:g "h"}) 什么是好的删除节点功能 (remove-node coll node) ;=> {:a ["b" {:c "d" :e ["f"]}]}) 谢谢 编辑: 我要做的是删除一个enlive节点 (def enlive-node [{:type :dtd, :data ["html" ni

我希望有一个函数可以从包含该节点的集合中删除任何节点(子集合)

(def coll {:a ["b" {:c "d" :e ["f" {:g "h"}]}]})
(def node {:g "h"})
什么是好的删除节点功能

(remove-node coll node)
;=> {:a ["b" {:c "d" :e ["f"]}]})
谢谢

编辑: 我要做的是删除一个enlive节点

(def enlive-node
  [{:type :dtd, :data ["html" nil nil]} 
   {:tag :html, 
    :attrs nil, 
    :content ["\n" 
              {:tag :head, 
               :attrs nil, 
               :content ["\n    \n    " 
                         {:tag :title, 
                          :attrs nil, 
                          :content ["Stack Overflow"]} 
                         "\n    " 
                         {:tag :link, 
                          :attrs {:href "//cdn.sstatic.net/stackoverflow/img/favicon.ico", 
                                  :rel "shortcut icon"}, 
                                  :content nil}]}]}])
要删除的节点始终是字符串或整个哈希映射

(remove-node enlive-node {:tag :title, 
                              :attrs nil, 
                              :content ["Stack Overflow"]})

对于您的示例,可以使用
clojure.walk/postwark
遍历hashmap并删除节点

(require '[clojure.walk :as walk])

(defn remove-node [coll target]
  (walk/postwalk
    (fn [item]
      (if (vector? item)
        (filterv #(not= target %) item)
        item))
    coll))

(remove-node coll node)
编辑:

根据您更新的问题,您似乎正在对Enlive节点集合进行操作。在您的情况下,另一个解决方案是生成一个Enlive节点选择器,并使用
net.cgrand.Enlive html/at*
函数转换集合

(require '[net.cgrand.enlive-html :as e])

(defn gen-transform [target]
  [[(cond
     (string? target) e/text-node
     (map? target) (:tag target)
     :else e/any-node)]
   #(when (not= target %) %)])

(defn remove-node [coll & nodes]
  (e/at* coll (map gen-transform nodes)))

(remove-node enlive-node
             {:tag :title, :attrs nil, :content ["Stack Overflow"]}
             "\n")

您有更好的coll吗?
(删除节点coll{:c“d”})
的预期输出是什么?是返回
{:a[“b”]}
还是只返回
coll
的精确副本?这个coll是如何产生的?如果我可以问的话。@DaoWen我不认为
{:c[“d”]}
是coll的一个节点。@Igrapenthin我添加了一个更好的coll。这实际上是Enlive生产的。谢谢!使用enlive,我们只需要通过
(if(vector?item)
更改
(if(seq?item)
如果您已经在使用Enlive,为什么不使用
net.cgrand.Enlive html/at
并使用Enlive选择器语法和转换对其进行转换?如果我有选择器,我可以。在我的特定用例中,我不一定知道集合中的节点位于何处……这听起来像是一个有趣的问题。请尝试以下方法: