1
votes

I am merging two hashmaps in clojure, but it is giving unexpected results. Below are the two datasets I am merging:

({:TEST"E", :EMEA "0", :NA "0", :ASPAC "180"}
{:TEST"B", :EMEA "0", :NA "70", :ASPAC "0"}
{:TEST"D", :EMEA "38", :NA "0", :ASPAC "0"} 
{:TEST"C", :EMEA "0", :NA "0", :ASPAC "0"}
{:TEST"G", :EMEA "360", :NA "0", :ASPAC "0"}
{:TEST"A", :EMEA "45", :NA "0", :ASPAC "0"} 
{:TEST"F", :EMEA "0", :NA "0", :ASPAC "66"})


({:TEST"A", :EMEA_1 "40", :NA_1 "0", :ASPAC_1 "0"}
{:TEST"B", :EMEA_1 "90", :NA_1 "0", :ASPAC_1 "0"}
{:TEST"H", :EMEA_1 "0", :NA_1 "120", :ASPAC_1 "0"} 
{:TEST"C", :EMEA_1 "0", :NA_1 "85", :ASPAC_1 "0"})

I am expecting to see somethig like this:

({:TEST"A", :EMEA "45", :NA "0", :ASPAC "0", :EMEA_1 "40", :NA_1 "0", :ASPAC_1 "0"}
{:TEST"B", :EMEA "0", :NA "70", :ASPAC "0", :EMEA_1 "90", :NA_1 "0", :ASPAC_1 "0"}
{:TEST"C", :EMEA "0", :NA "0", :ASPAC "0",  :EMEA_1 "0", :NA_1 "85", :ASPAC_1 "0"}
{:TEST"D", :EMEA "38", :NA "0", :ASPAC "0", :EMEA_1 nil, :NA_1 nil, :ASPAC_1 nil}
{:TEST"E", :EMEA "0", :NA "0", :ASPAC "180", :EMEA_1 nil, :NA_1 nil, :ASPAC_1 nil}
{:TEST"F", :EMEA "0", :NA "0", :ASPAC "66", :EMEA_1 nil, :NA_1 nil, :ASPAC_1 nil}
{:TEST"G", :EMEA "360", :NA "0", :ASPAC "0", :EMEA_1 nil, :NA_1 nil, :ASPAC_1 nil}
{:TEST"H", :EMEA nil, :NA nil, :ASPAC nil, :EMEA_1 "0", :NA_1 "120", :ASPAC_1 "0"})

I have tried using merge, merge-wth, apply merge-with but nothing is giving me the results I expected.

Any adivse on how I can get to my desired resultset or why I am actually not geting what I am expecting would also be helpful.

Thanks you.

1
You're not dealing with two hash maps, you're dealing with 2 seqs, each containing multiple hashmaps. Can you show something of the code you've tried?Joost Diepenmaat
You need to revise your data structure. Is :TEST "A" supposed to be the key for each "row" of your table?noahlz

1 Answers

5
votes

Given your two collections are defined as coll1 and coll2:

(map (partial apply merge) (-> (clojure.set/union coll1 coll2)
                               (clojure.set/index [:TEST])
                               vals))

should lead to your desired result.

If you don't want clojure.set you may also use

(map (partial apply merge) (->>  (concat coll1 coll2)
                                 (group-by :TEST)
                                 vals))

However looking at your data structures, they rather look like a case for clojure.set.

You may note that the result will not have [:key nil] like entries. If you want them, there certainly is a way but relying on them goes against the meaning of nil as nothing.