Clojure Submaps
The gentleman behind Clojure Diary was kind enough to recently post a video based on a small comment I made on his YouTube channel: Clojure Diary - Elegant way of filtering maps based on key value pairs.
(Please check out his channel as he’s doing a great job regularly posting videos about his journey through Clojure!)
In my comment I used a little submap?
function from my personal
utilities library that I’ve gotten a lot of mileage out of the last
year or two.
I thought I’d mention it here. It’s isn’t anything magical, but I think it’s part of my personal standard library from here on out:
(defn submap?
"Are all of the key-value pairs in `m1` also in `m2`?"
[m1 m2]
(= m1 (select-keys m2 (keys m1))))
(submap {:a 1, :b 2} {:a 1, :b 2, :c 3}} ; => true
(submap {:a 1, :b 2} {:a 1, :b 4, :c 3}} ; => false
One of the things I use it for constantly is unit tests where I want to assert that a map contains multiple key-value pairs, but I don’t want to assume that a map contains only the specified key-value pairs (in the spirit of the open-world assumption)1.
It also plays nicely with clojure.test
, yielding useful test output
which shows the full value tested against:
Fail in handler
expected: (utils/submap? {:status 200} (sut/handler {:method :get, :path "/"}))
actual: (not
(utils/submap?
{:status 200}
{:status 404,
:body "Not Found",
:headers {"Content-type" "text/html"}}))
I hear https://github.com/nubank/matcher-combinators is another great option here if you’re ready to invite a new dependency into your project. ↩︎