Clojure

Clojure: does a map contain all the specified keys?

An interesting problem came up this week during some Clojure batch work. How do you cleanly say that a map contains a set of given keys? The context is that during batch processing you only want to perform some operations if earlier operations have populated the right data set.

There’s probably some neat trick or built-in function but this is what I’ve come up with. I quite like the mapping of the count, it would look even better if I didn’t have to apply the equals but it’s not bad.

(defn has-keys? [m keys]
  (apply = (map count [keys (select-keys m keys)])))

(def map-data {:a 1 :b 3})

(has-keys? map-data [:a :c]) ; false

(has-keys? map-data [:a :b]) ; true
Standard

6 thoughts on “Clojure: does a map contain all the specified keys?

  1. IMHO, this implementation is a little bit clear and efficient (the first not found key the entire function will evaluate to false):

    (defn has-keys? [m keys]
      (every? #(contains? m %1) keys))
    
    
    user=> (def map-data {:a1 :b 3})
    #'user/map-data
    user=> (has-keys? map-data [:a :c])
    false
    user=> (has-keys? map-data [:a :b])
    true
    

    Cheers,

    Jonas

  2. Or even better (it depends if you like point-free programming, IMHO it is clean than using the positional parameter but you may prefer the other way around):

    (defn has-keys? [m keys]
      (every? (partial contains m) keys))
    

    Cheers,

    Jonas

Leave a comment