Skip to content

Instantly share code, notes, and snippets.

@martintrojer
Last active December 14, 2015 05:40
Show Gist options
  • Save martintrojer/5036956 to your computer and use it in GitHub Desktop.
Save martintrojer/5036956 to your computer and use it in GitHub Desktop.
filter-map-entries
(defn re?
([p]
(fn [s] (re-find (re-pattern p) (str s))))
([p s] ((re? p) s)))
(defn mapentry-matches? [pat [k v]]
(or (re? pat (-> k str string/lower-case))
(re? pat (-> v str string/lower-case))))
;; filter keys and values in json-like nested maps and vectors
(defn filter-map-entries [pred m]
(loop [acc [], [[k v] & tail] (seq m)]
(if k
(cond (pred [k k]) (recur (conj acc [k v]) tail)
(map? v) (let [submap (filter-map-entries pred v)]
(if (empty? submap)
(recur acc tail)
(recur (conj acc [k submap]) tail)))
(vector? v) (let [ms (for [av v
:let [submap (if (coll? av)
(filter-map-entries pred av)
(if (pred [av av]) [av] []))]
:when (not (empty? submap))]
(first submap))]
(if (empty? ms)
(recur acc tail)
(recur (conj acc [k (vec ms)]) tail)))
:else (if (pred [k v]) (recur (conj acc [k v]) tail) (recur acc tail)))
acc)))
(defn fme [pat-str m]
(let [pat (-> pat-str string/lower-case java.util.regex.Pattern/compile)]
(pprint/pprint (filter-map-entries (partial mapentry-matches? pat) m))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment