Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing items from a map based on the contents of another map

Tags:

clojure

Still working through Programming Collective Intelligence and using Clojure to write the code. I've got it working, but some parts are really ugly, so I thought I'd ask some of the experts around here to help clean it up.

Let's suppose I have a map that looks like this (bound to "recs"):

{"Superman Returns" 3.902419556891574, "Lady in the Water" 2.8325499182641614, 
"Snakes on a Plane" 3.7059737842895792, "The Night Listener" 3.3477895267131017,
"You, Me and Dupree" 2.651006036204627, "Just My Luck" 2.5309807037655645}

and I want to remove those items with keys that are also in the map (bound to "mymovies"):

{"Snakes on a Plane" 4.5, "You, Me and Dupree" 1.0, "Superman Returns" 4.0}

so that I get the map:

{"Lady in the Water" 2.8325499182641614, "The Night Listener" 3.3477895267131017,
"Just My Luck" 2.5309807037655645}

the code that I managed to get to do this looks like:

(apply merge (map #(hash-map (first %) (second %))
              (remove #(contains? mymovies (first %))
                      recs)))

That seems pretty ugly to me. It doesn't seem like it should be necessary to create a map from the value I get back from "remove". Is there a cleaner way to do this?

UPDATE: Joost's answer below sparked another idea. If I turn the keys of the two maps into sets I can use select-keys like this:

(select-keys recs (difference (set (keys recs))
                              (set (keys mymovies))))

Joost, thanks for turning me on to select-keys. I didn't know about that function before. Now to go rewrite several other sections with this new found knowledge!

like image 504
Dave Kincaid Avatar asked Sep 05 '11 19:09

Dave Kincaid


1 Answers

(apply dissoc recs (keys mymovies))
like image 66
ponzao Avatar answered Oct 10 '22 04:10

ponzao