2014-06-27 121 views
1

我有以下結構的兩個地圖:合併地圖Clojure中

(def a {:key1 10, :key2 100}) 
(def b {:key1 50, :key3 10}) 

我想形式的輸出:

{:key1 {:val1 10, :val2 50}, 
:key2 {:val1 100, :val2 nil}, 
:key3 {:val1 nil, :val2: 10}} 

我看着merge-with,但只適用功能時,鍵存在於兩個地圖中。另一種解決方案是從兩個地圖製作一組鍵,然後減少它以製作我想要的結構,但這並不覺得「慣用」的Clojure。

+0

這是一個幾乎複製https://stackoverflow.com/questions/9408846/in-clojure-how-to-merge-several-maps-combining-mappings-with-same-key-into-的一個立?RQ = 1。 – dg123

+0

我在發帖前檢查了這個問題,但它與我想要的不同。 –

回答

1
(defn my-merge [labeled-maps] 
    (->> (for [[label m] labeled-maps 
       [k v] m] 
      {k {label v}}) 
     (apply merge-with merge))) 

(def merged (my-merge {:val1 a, :val2 b})) 

merged 
;=> {:key3 {:val2 10}, :key1 {:val2 50, :val1 10}, :key2 {:val1 100}} 

你並不需要或想要的關鍵丟失時引入明確的尼爾斯。這將使源地圖中合法的nil值與合併引入的nil無法區分。

(get-in [:key3 :val1] merged) 
;=> nil (either no value for :key3 in the map labeled :val1 or the value was nil) 

(get-in [:key3 :val1] merged ::not-found) 
;=> :user/not-found (this is clear here since we did not introduce any new nils)