2012-03-15 20 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))) 

關於執行的關鍵事項:

  • 這是有道理的後代轉換成一組:這將允許快速成員測試,如果設定鍵刪除的是大
  • 有一些邏輯,以確保如果一個值不會改變,你不不需要改變那部分地圖。如果地圖的大面積不變,這將是一個非常大的表現。