A clj snippet #1
I haven't be blogging much recently and I still have the goal to write a total of 52 blogs posts this year. Even though the recent circumstances should give plenty of time to write, I have, so far, not found the willpower. The Why Not a Function series is setting a good example for short informative Clojure blog posts. So I took that as an inspiration and will try to start a little spinoff series called A clj snippet.
Today's snippet is stolen from the Ring clojure library.
(defn assoc-conj
"Associate a key with a value in a map. If the key already exists in the map,
a vector of values is associated with the key."
[map key val]
(assoc map key
(if-let [cur (get map key)]
(if (vector? cur)
(conj cur val)
[cur val])
val)))
assoc-conj
helps you deal with associative data where the keys are not unique. Where might this be useful? Consider urls which apparently can have multiple values per parameter name.
(require [clojure.string :as str])
(let [url "http://server/action?id=a&id=b&token=xyz"
[_ params] (str/split url "\?")] ;; only for presentation purposes
(reduce
(fn [m param]
(if-let [[k v] (str/split param "=" 2)]
(assoc-conj m (keyword k) v)
m))
{}
(str/split params "&")))
This of course ignores some important parts like decoding. Urls can also be a lot more tricky than the one above. Keep safe and happy hacking.