我有两个地图数组
1st是[{:a 1 :b 2 :d 6} {:a 2 :b 2} {:a 7 :b 7}]
第二名是[{:a 3 :c 3 :e 9 :y 7} {:a 2 :b 6 :c 8}]
取决于a
的值,即如果它在第二个数组中匹配,则“第二个地图”应该与“第一个地图”合并,并且结果数组应该是
Res应为[{:a 1 :b 2 :d 6} {:a 2 :b 6 :c 8} {:a 7 :b 7} {:a 3 :c 3 :e 9 :y 7}]
任何人都可以帮助我。提前谢谢。
答案 0 :(得分:6)
你走了:
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})
答案 1 :(得分:4)
这个数据结构对我来说看起来非常笨拙,但这是我的看法:
(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)))
它没有做的一件事是保持输入列表的顺序,但由于不清楚哪个列表决定(两个可能在不同的顺序中都有相同的键),我把它排除在外。
答案 2 :(得分:0)
也许clojure.set / join就是你想要的:
这是clojure.set/join的文档:
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"}}