11.04.2010

clojure map-keys

Someone in #clojure was asking about how to case-insensitively check the keys of a map. The best answer anyone present at the time came up with was pre-processing the map by naming, lowering, and keywordifying the keywords. We then found out the asker was looking for keys in nested maps, so I wrote a function for that.

After writing the function I realized I could extract the lowering function and let it take a function to apply to all keys of m and all keys in m's vals.

Here is the map-keys function with the lower-key function extracted. I run it on some goofy data at the end. Try it in a REPL.

(defn lower-key [x]
(if (or (string? x) (keyword? x))
(-> x name .toLowerCase keyword)
x))
(defn map-keys
"applies f to each key of m. also to keys of m's vals and so on."
[f m]
(zipmap
(map (fn [k]
(f k))
(keys m))
(map (fn [v]
(if (map? v)
(map-keys f v)
v))
(vals m))))
(map-keys lower-key
{:aBaB 123
"CAsasas" {1 "doesn't apply to non-string non-keyword keys"
:yoGURt "mmMMm"
:notVALUES "either"}})
view raw map-keys.clj hosted with ❤ by GitHub

No comments:

Post a Comment