Elegant way of filtering maps based on key value pairs

less than 1 minute read

Code

;; search_and_compare_maps.clj

(def users [{"email" "a@a.com",
             "password" "aaaa"},
            {"email" "b@b.com"
             "password" "bbbb"}])

(defn maps-having  [m ms]
  (filter #(every? (fn [[k v]] (= v (% k))) m) ms))

(maps-having {"email" "a@a.com" "password" "aaaa"} users)


;; https://clojuredocs.org/clojure.core/every_q
(every? even? [1 2 3 4 5])

(every? even? [2 4 6 8])

(defn submap?
  "Are all of the key-value pairs in `m1` also in `m2`?"
  [m1 m2]
  (= m1 (select-keys m2 (keys m1))))

(submap? {"email" "a@a.com"} (first users))

;; https://clojuredocs.org/clojure.core/select-keys
(select-keys {:a 1 :b 2} [:a])

(select-keys {:a 1 :b 2 :c 5} [:a :b])

;; https://clojuredocs.org/clojure.core/partial
(defn maps-having-with-submap [m ms]
  (filter (partial submap? m) ms))

(maps-having-with-submap {"email" "a@a.com"} users)

(defn maps-compare  [m ms compare-fn]
  (filter #(every? (fn [[k v]] (compare-fn v (% k))) m) ms))

(defn map-greater? [m ms]
  (maps-compare m ms >))

(map-greater? {:a 20 :b 50} [{:a 5 :b 7 :c 12}])

(map-greater? {:a 20 :b 50 :c 10} [{:a 5 :b 7 :c 12}
                                   {:a 7 :b 9 :c 3}])

(map-greater? {:a 20 :b 50 :c 10} [{:a 5 :b 7 :c 12}
                                   {:a 7 :b 9 :c 30}])

Notes

Updated: