2012-03-15 57 views
5

如何搜索和分解多个后代密钥。解析地图的多个后代键?

例子:

(def d {:foo 123 
     :bar { 
      :baz 456 
      :bam { 
      :whiz 789}}}) 

(dissoc-descendents d [:foo :bam]) 
;->> {:bar {:baz 456}} 

回答

6

clojure.walk在这种情况下非常有用:

(use 'clojure.walk) 
(postwalk #(if (map? %) (dissoc % :foo :bam) %) d) 
+3

人行道做深度优先遍历。我想对于这种情况,广度优先遍历搜索的效率会更好,因为如果要删除父节点,那么我们不需要遍历其子节点 – Ankur 2012-03-16 04:54:43

1

如果你想直接执行它,那么我建议是这样的:

(defn dissoc-descendents [coll descendents] 
    (let [descendents (if (set? descendents) descendents (set descendents))] 
    (if (associative? coll) 
     (reduce 
     (fn [m [k v]] (if (descendents k) 
         (dissoc m k) 
         (let [new-val (dissoc-descendents v descendents)] 
          (if (identical? new-val v) m (assoc m k new-val))))) 
     coll 
     coll) 
     coll))) 

关于执行的关键事项:

  • 这是有道理的后代转换成一组:这将允许快速成员测试,如果设定键删除的是大
  • 有一些逻辑,以确保如果一个值不会改变,你不不需要改变那部分地图。如果地图的大面积不变,这将是一个非常大的表现。