Clojure 合并基于键的映射列表

Clojure merge list of maps based on keys

我需要转换以下数据:

[{["A" 1] [{:ms "A", :s 1, :v 15}], ["A" 2] [{:ms "A", :s 2, :v 18}], ["A" 4] [{:ms "A", :s 4, :v 19}]}
 {["A" 1] [{:ms "A", :s 1, :v2 5}], ["A" 2] [{:ms "A", :s 2, :v2 8}], ["B" 4] [{:ms "B", :s 4, :v2 9}]}]

至:

[{:ms "A", :s 1, :v 15, :v2 5} {:ms "A", :s 2, :v 18, :v2 8} {:ms "A", :s 4, :v 19} {:ms "B", :s 4, :v2 9}]

我正在努力实施,如有任何帮助,我们将不胜感激:)

这会起作用:

(def data [{["A" 1] [{:ms "A", :s 1, :v 15}],
            ["A" 2] [{:ms "A", :s 2, :v 18}],
            ["A" 4] [{:ms "A", :s 4, :v 19}]}
           {["A" 1] [{:ms "A", :s 1, :v2 5}],
            ["A" 2] [{:ms "A", :s 2, :v2 8}],
            ["B" 4] [{:ms "B", :s 4, :v2 9}]}])

(map (partial apply merge) (vals (apply merge-with concat data)))

这里有一步一步的解释:

首先我们合并所有顶层映射,连接等键的值:

(apply merge-with concat data)
;;=> {["A" 1] ({:ms "A", :s 1, :v 15} {:ms "A", :s 1, :v2 5}), 
;;    ["A" 2] ({:ms "A", :s 2, :v 18} {:ms "A", :s 2, :v2 8}), 
;;    ["A" 4] [{:ms "A", :s 4, :v 19}], 
;;    ["B" 4] [{:ms "B", :s 4, :v2 9}]}

然后对于地图中的每个值,我们应该执行合并到一个地图:

(apply merge '({:ms "A", :s 1, :v 15} {:ms "A", :s 1, :v2 5}))
;;=> {:ms "A", :s 1, :v 15, :v2 5}

所以我们应该使用 map:

(map (partial apply merge) (vals (apply merge-with concat data)))
;;=> ({:ms "A", :s 1, :v 15, :v2 5}
;;    {:ms "A", :s 2, :v 18, :v2 8}
;;    {:ms "A", :s 4, :v 19}
;;    {:ms "B", :s 4, :v2 9})