fredag 22 mars 2013

merge-with to the rescue

I'm working on coloring a map with different colors, that sometimes overlap.

After deep though I found out that I could have colorings in maps and then merge the maps somehow. This doesn't work perfectly, but it's a good start. After fiddling around with home-brewed solutions I looked in core.clj for merge in the source code and found merge-with just below. Perfect match.

A short example of the power of merge-with:

(def scandinavia (zipmap ["sweden" "norway" "denmark" "aaland" "iceland" "finland" "greenland" "fareoes"] (repeat :yellow)))
=>{"fareoes" :yellow, ...

(def swedish-speaking (zipmap ["sweden" "aeland" "finland" "ukraine" ] (repeat :red)))
=>{"ukraine" :red, ... * see below for Swedish language in Ukraine

(defn blend [a b] :orange)

(merge-with blend scandinavia swedish-speaking)

{"ukraine" :red, 
"fareoes" :yellow, 
"greenland" :yellow, 
"finland" :orange, 
"iceland" :yellow, 
"aaland" :orange, 
"denmark" :yellow, 
"norway" :yellow, 
"sweden" :orange}

As you can I cheated quite extensively with the blend function, but in this case it doesn't matter, since we're always blending yellow and red if we are blendning.

Merge-with uses the function given (blend) if two keys are colliding when merging. If you want to sum to maps, use (merge-with + {:x 1 :y 2} {:x 3}) and get {:x 4 :y 2}.

* And yes, there are some really old ladies speaking Swedish in Ukraine in the Gammalsvenskby.

Inga kommentarer:

Skicka en kommentar