renanreismartins
renanreismartins

Reputation: 309

intersection between two maps in clojure

I have hash-maps and I'm trying to get the intersection between the keys. But the function 'intersection' just work with sets.

So I'm getting the keys, transforming the keys to sets and then calling the intersection, something like this:

(intersection (set (keys map-1)) (set (keys map-2)))

There are a better way to do that?

Thanks

Upvotes: 3

Views: 2399

Answers (3)

beoliver
beoliver

Reputation: 5759

The following should work for arbitrary numbers of maps

(defn key-intersection [m & ms]
  (reduce #(keys (select-keys %2 %1)) (keys m) ms))

or

(defn key-intersection [m & ms]
  (reduce (fn [v c] (keep #(some->> % (find c) key) v)) (keys m) ms))

Upvotes: 1

noisesmith
noisesmith

Reputation: 20194

This may be the most straightforward / concise way to do it, and it doesn't require building any sets (which is relatively expensive).

(keys (select-keys map-1 (keys map-2)))

Finally, an optimized version, which is a bit faster, and a bit harder to read:

(keep #(some->> % (find map-1) key) (keys map-2))

Upvotes: 7

Thumbnail
Thumbnail

Reputation: 13473

Your solution is clear and concise.

If performance is a concern, you can avoid constructing the intermediate sets by imitating the structure of clojure.set/intersection:

(defn key-intersection [s1 s2]
  (if (< (count s2) (count s1))
    (recur s2 s1)
    (reduce
     (fn [result item]
       (if (contains? s2 item)
         (conj result item)
         result))
     #{}
     (keys s1))))

Upvotes: 2

Related Questions