按UUID合并地图列表

时间:2016-05-20 14:48:07

标签: clojure

我有两张地图列表

(def map1 ({:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0", :book/name "AAA"}
           {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3", :book/name "CCC"}))

(def map2 ({:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3", :book/author "John"}
           {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0", :book/author "Alan"}))

我希望通过UUID合并这些地图以获得以下

({:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0", :book/name "AAA", :book/author "Alan"}
 {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3", :book/name "CCC", :book/author "John"})

我可以用它做什么?

3 个答案:

答案 0 :(得分:2)

(defn group-by-id [m]
  (->> m
      (map (juxt :book/public-id identity))
      (into {})))

(vals (merge-with merge (group-by-id map1) (group-by-id map2)))

答案 1 :(得分:2)

如果您有向量而不是列表,则可以使用连接在匹配值上合并这些集:

user=> (def map1 [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0", :book/name "AAA"}
  #_=>         {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3", :book/name "CCC"}])
#'user/map1
user=> (def map2 [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3", :book/author "John"}
  #_=>    {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0", :book/author "Alan"}])
#'user/map2
user=> (clojure.set/join map1 map2)
#{{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3", :book/name "CCC", :book/author "John"} {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0", :book/name "AAA", :book/author "Alan"}}

答案 2 :(得分:2)

您可以使用合并来执行此操作。我重新命名了vars,使其更加清晰。此外,我使用向量来表示集合,因为它更具惯用性:

(def titles
  [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0"
    :book/name "AAA"}
   {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
    :book/name "CCC"}])

(def authors
  [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
    :book/author "John"}
   {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0"
    :book/author "Alan"}])

(def prices
  [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
    :book/price 25}])

我创建了一个价格变量以显示向量不需要相同的大小。第一步是将每个书籍信息分组到一个结构中,然后我们可以使用merge为每本书获取一个地图。为此,我们可以使用group-by

(def book-info-by-uuid
  (group-by :book/public-id (concat titles authors prices)))

这将为我们提供一张uuid作为键的地图和一张载有每本书所有信息作为值的向量:

{#uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0"
 [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0"
   :book/name "AAA"}
  {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0"
   :book/author "Alan"}]

 #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
 [{:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
   :book/name "CCC"}
  {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
   :book/author "John"}
  {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
   :book/price 25}]}

最后,我们使用merge来获得结果:

(map #(apply merge %)
       (vals books-by-uuid))

({:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c0"
  :book/name "AAA"
  :book/author "Alan"}
 {:book/public-id #uuid "555b6f35-4e8c-42c5-bb80-b4d9147394c3"
  :book/name "CCC"
  :book/author "John"
  :book/price 25})