Intersection between two cards in clojure

I have hash maps and I am trying to get the intersection between the keys. But the intersection function only works with sets.

So, I get the keys by converting the keys to sets and then call the intersection, something like this:

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

      

Is there a better way to do this?

thank

+3


source to share


3 answers


This may be the simplest or most concise way to do it, and does not require creating any sets (which is relatively expensive).

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

      



Finally, an optimized version that is slightly faster and a little harder to read:

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

      

+6


source


Your solution is clear and concise.

If performance is an issue, you can avoid creating intermediate sets by mimicking the clojure.set / intersection structure :



(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))))

      

+2


source


For arbitrary numbers of mappings

(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))

      

+1


source







All Articles