2014-03-26 33 views
5

我有一個結構類似的嵌套HashMap中的以下內容:如何在嵌套的散列表中合併?

(def pathmap {:order {:genus {:species {:cat2 "data", :cat1 "data"}}}}) 

我需要的是像一個函數assoc命令式,讓我到新的鍵值對添加到內部嵌套地圖,而不是簡單地取代已有的東西。例如:

(my-assoc-merge pathmap [:order :genus :species] {:cat3 "data"}) 
;=> {:order {:genus {:species {:cat3 "data" :cat2 "data", :cat1 "data"}}}} 

我想我也許可以通過改變assoc命令,在功能上略有使用合併,與和工會要做到這一點很容易不夠:

(defn my-assoc-merge 
    [m [k & ks] v] 
    (if ks 
    (assoc m k (my-assoc-merge (get m k) ks v)) 
    (assoc m k (merge-with clojure.set/union (get m k '{}) v)))) 

很不幸,這給我的錯誤「CompilerException java.lang.UnsupportedOperationException:此類型不支持count:關鍵字,編譯:(core.clj:34:12)」。我哪裏錯了?

回答

5

實際上,assoc-in已經創建一個新的密鑰,如果它不存在。用法如下:

(def pathmap {:order {:genus {:species {:cat2 "data", :cat1 "data"}}}}) 

(assoc-in pathmap [:order :genus :species :cat3] "data") 
;=> {:order {:genus {:species {:cat2 "data", :cat3 "data", :cat1 "data"}}}} 

如果您希望合併新地圖,使用update-inmerge

(update-in pathmap [:order :genus :species] merge {:cat3 "data"}) 
;=> {:order {:genus {:species {:cat2 "data", :cat3 "data", :cat1 "data"}}}} 

的問題與您my-assoc-merge是在工作組的union。將merge-with更改爲merge並丟棄union

+1

輝煌燦爛的語言功能。 – leontalbot

+0

'update-in'完全符合我的要求。也感謝修正。 – patabongo