Clojure,合并两个地图数组

Clojure,合并两个地图数组,clojure,Clojure,我有两组地图 第一个是[{:a1:b2:d6}{:a2:b2}{:a7:b7}] 第二个是[{:a3:c3:e9:y7}{:a2:b6:c8}] 根据a的值,即如果其在第二个数组中匹配,“第二个贴图”应与“第一个贴图”合并,并且生成的贴图数组应为 Res应该是[{:a1:b2:d6}{:a2:b6:c8}{:a7:b7}{:a3:c3:e9:y7}] 有人能帮我吗。提前感谢。这个数据结构在我看来非常笨拙,但我的看法是: (defn key-by-a [coll] "Convert a lis

我有两组地图

第一个是
[{:a1:b2:d6}{:a2:b2}{:a7:b7}]

第二个是
[{:a3:c3:e9:y7}{:a2:b6:c8}]

根据
a
的值,即如果其在第二个数组中匹配,“第二个贴图”应与“第一个贴图”合并,并且生成的贴图数组应为

Res应该是
[{:a1:b2:d6}{:a2:b6:c8}{:a7:b7}{:a3:c3:e9:y7}]


有人能帮我吗。提前感谢。

这个数据结构在我看来非常笨拙,但我的看法是:

(defn key-by-a [coll]
  "Convert a list of maps to a map of maps keyed by their vals at :a"
  (apply hash-map (mapcat (juxt :a identity) coll)))

(defn merge-map-lists [l1 l2]
  (->> [l1 l2]
    (map key-by-a)
    (apply merge-with merge)
    (vals)))
它没有做的一件事是维护输入列表的顺序,但由于不清楚哪个列表决定(两个列表可能具有不同顺序的相同键),所以我忽略了这一点。

给您:

user> (def xs [{:a 1 :b 2 :d 6} {:a 2 :b 2} {:a 7 :b 7}])
#'user/xs
user> (def ys  [{:a 3 :c 3 :e 9 :y 7} {:a 2 :b 6 :c 8}])
#'user/ys
user> (for [[a ms] (group-by :a (concat xs ys))] (apply merge ms))
({:a 1, :b 2, :d 6} {:a 2, :c 8, :b 6} {:a 7, :b 7} {:y 7, :a 3, :c 3, :e 9})

也许clojure.set/join就是您想要的:

以下是以下文件:


我不太确定算法是什么,换句话说,我不太确定要比较什么来得到“Res”。我比较的是键“a”的值。如果第一个映射的“a”值与第二个数组中任何映射的“a”值匹配,则执行此操作(合并{1st map have'a'value=1}{2nd map have'a'value=1}),并将此结果映射添加到最终映射
user=> (def animals #{{:name "betsy" :owner "brian" :kind "cow"}
                      {:name "jake"  :owner "brian" :kind "horse"}
                      {:name "josie" :owner "dawn"  :kind "cow"}})

user=> (def personalities #{{:kind "cow" :personality "stoic"}
                            {:kind "horse" :personality "skittish"}})
#'user/personalities
user=> (join animals personalities)

#{{:owner "dawn",  :name "josie", :kind "cow",   :personality "stoic"}
  {:owner "brian", :name "betsy", :kind "cow",   :personality "stoic"}
  {:owner "brian", :name "jake",  :kind "horse", :personality "skittish"}}

user=> (join animals personalities)
#{{:kind "horse", :owner "brian", :name "jake", :species "cow", :personality "stoic"}
  {:kind "cow", :owner "dawn", :name "josie", :species "cow", :personality "stoic"}
  {:kind "horse", :owner "brian", :name "jake", :species "horse", :personality "skittish"}
  {:kind "cow", :owner "brian", :name "betsy", :species "cow", :personality "stoic"}
  {:kind "cow", :owner "dawn", :name "josie", :species "horse", :personality "skittish"}
  {:kind "cow", :owner "brian", :name "betsy", :species "horse", :personality "skittish"}}


;; Notice that "Jake" is both a horse and a cow in the first line. That's 
;; likely not what you want. You can tell `join` to only produce output 
;; where the `:kind` value is the same as the `:species` value like this:

user=> (join animals personalities {:kind :species})
#{{:kind "cow", :owner "dawn", :name "josie", :species "cow", :personality "stoic"}
  {:kind "horse", :owner "brian", :name "jake", :species "horse", :personality "skittish"}
  {:kind "cow", :owner "brian", :name "betsy", :species "cow", :personality "stoic"}}