Skip to content

Instantly share code, notes, and snippets.

@spacegangster
Created November 9, 2021 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spacegangster/9b3cbbd3bfb311e5703c4abcd94e83cc to your computer and use it in GitHub Desktop.
Save spacegangster/9b3cbbd3bfb311e5703c4abcd94e83cc to your computer and use it in GitHub Desktop.
Simple Clojure[Script] matching function
(ns common.match)
"Example:
(def your-map {:status 200, body 'something}
(m {:status 200} your-map) => true
"
(declare has-matching-values?)
(defn m [template-value actual] ; matcher
(cond
(map? template-value)
(and
(map? actual)
(every? true?
(for [k (keys template-value)]
(and (contains? actual k)
(m (get template-value k) (get actual k))))))
(set? template-value)
(has-matching-values? template-value actual)
(vector? template-value)
(every? true?
(for [i (range (count template-value))
:let [new-template-value (nth template-value i)]]
(and (contains? actual i)
(or (= ::any new-template-value)
(m new-template-value (nth actual i))))))
(= ::empty-or-none template-value) (empty? actual)
(= ::any template-value) (some? actual)
(= ::any-or-nil template-value) (or (some? actual) (nil? actual))
:else (= template-value actual)))
(defn has-matching-values? [template-values-set checked-set]
(every?
(fn [template-v]
(some #(m template-v %) checked-set))
template-values-set))
(assert (not (m {:a ::any} nil)))
(assert (not (m {:a ::any} "")))
(assert (m {:a ::any-or-nil} {:a nil}))
(assert (not (m {:a ::any} {:a nil})))
(assert (not (m {:a {:b 4 :c {:d 0}}} {:a {:b 4 :c {:d 1}}})))
(assert (m {:a {:b 4 :c {:d ::any}}} {:a {:b 4 :c {:d 1}}}))
(assert (m {:a ::any} {:a "text"}))
; subset matching
(assert (m #{::any :a} #{:a "text"}))
(assert (not (m #{:b} #{:a "text"})))
(assert (m [::any 2] [1 2]))
(assert (not (m [::any 2] [1 3])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment