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选择器语法和转换对其进行转换?如果我有选择器,我可以。在我的特定用例中,我不一定知道集合中的节点位于何处……这听起来像是一个有趣的问题。请尝试以下方法: