如何合并clojure中的地图列表

时间:2018-04-30 14:48:39

标签: clojure

我获得了一份清单地图:

(->> (sort-by :a)
     (partition-by :a)
     (map (partial apply merge)))

我需要将它们组合起来,最终看起来像这样:

({:a 1 :b ["yellow"]} {:a 2 :b ["orange"]}) 

根据键的值" a"组合地图。 到目前为止,我有这个

mtree

但合并将覆盖" b"最后一个给了我

{{1}}

2 个答案:

答案 0 :(得分:3)

而不是merge,请使用merge-with,即

(->> a (sort-by :a) 
       (partition-by :a) 
       (map (partial 
          apply 
          merge-with (fn [x y] (if (= x y) x (into x y))))))

输出

({:a 1, :b ["red" "blue" "yellow"]} {:a 2, :b ["green" "orange"]})

答案 1 :(得分:0)

你真的不想对任何事情进行排序或分区:这只是在没有任何事情上花费的CPU时间,最后你有一个笨拙的数据结构(地图列表)而不是更方便的东西,一个由"重要"键入的地图; :a值。merge-with

相反,我会将其写为reduce,其中每个步骤在最终地图的相应子部分使用(defn combine-by [k ms] (reduce (fn [acc m] (update acc (get m k) (partial merge-with into) (dissoc m k))) {}, ms))

user=> (combine-by :a '({:a 1 :b ["red" "blue"]} 
                        {:a 2 :b ["green"]} 
                        {:a 1 :b ["yellow"]} 
                        {:a 2 :b ["orange"]}))
{1 {:b ["red" "blue" "yellow"]}, 2 {:b ["green" "orange"]}}

之后我们

:a

非常有用,可以通过特定{{1}}轻松查找地图,或者如果您希望将结果作为列表退回,则可以轻松展开。