Convert Map to string for use in URL as parameters question

1,165 views
Skip to first unread message

Brad

unread,
Aug 1, 2011, 6:47:02 PM8/1/11
to Clojure
I wanted to take a Map and convert it to a string suitable for use as
parameters in a URL. I have got it working below two different ways
but wondered if there was a better or more idiomatic way to do this.

;; My test input map
(def input {:a 1 :b 2 :c 3 :d 4})

;; What I'd like the input map convert into. A string that looks like
keyword=value&keyword=value&, ....
(def output "a=1&b=2&c=3&d=4")

;; This function converts each MapEntry to the key=value
(defn map-entry-to-string-pair
"Convert a key value from a map into a string that looks like
key=value.
For example,
(def input {:a 1 :b 2 :c 3 :d 4})
(map-entry-to-string-pair (first input)) => \"a=1\""
[mapentry]
(str (name (first mapentry)) "=" (second mapentry)))


;; The following two functions build the result string. There is not
much of a difference between them. The first uses
;; let to hold a variable after mapping map-entry-to-string-pair over
the input map. The other just uses the same mapping
;; after converting it to a vector.

(defn convert-map-to-url-string1
"Convert a map from keyword values to a string that consists of
keyword=value pairs separated by &s for use in a URL
For example,
(def input {:a 1 :b 2 :c 3 :d 4})
(convert-map-to-url-string1 input) => \"a=1&b=2&c=3&d=4\""
[m]
(let [pairs (map map-entry-to-string-pair m)]
(join "&" pairs)))

(defn convert-map-to-url-string2
"Convert a map from keyword values to a string that consists of
keyword=value pairs separated by &s for use in a URL
For example,
(def input {:a 1 :b 2 :c 3 :d 4})
(convert-map-to-url-string2 input) => \"a=1&b=2&c=3&d=4\""
[m]
(join "&" (vec (map map-entry-to-string-pair m))))


Is there a simpler, better way to do this?

- Brad

Sean Corfield

unread,
Aug 2, 2011, 12:19:23 AM8/2/11
to clo...@googlegroups.com
On Mon, Aug 1, 2011 at 3:47 PM, Brad <br...@beaconhill.com> wrote:
> ;; My test input map
> (def input {:a 1 :b 2 :c 3 :d 4})
...

> Is there a simpler, better way to do this?

How about:

(require '[clojure.string :as str])

(defn map-to-query-string [m]
(str/join "&" (map (fn [[k v]] (str (name k) "=" v)) m)))
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Matjaz Gregoric

unread,
Aug 2, 2011, 12:51:19 AM8/2/11
to clo...@googlegroups.com
Depending on your input, you might also want to make sure to properly urlencode the keys and values.
There is a function in hiccup that does what you want (including urlencoding):

https://github.com/weavejester/hiccup/blob/10c3ebe175edc80eed1a0792ec68036be47940d3/src/hiccup/page_helpers.clj#L117-123



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Brad

unread,
Aug 2, 2011, 8:23:01 AM8/2/11
to Clojure
Thanks. This is much more succinct.


On Aug 2, 12:19 am, Sean Corfield <seancorfi...@gmail.com> wrote:
> On Mon, Aug 1, 2011 at 3:47 PM, Brad <b...@beaconhill.com> wrote:
> > ;; My test input map
> > (def input {:a 1 :b 2 :c 3 :d 4})
> ...
> > Is there a simpler, better way to do this?
>
> How about:
>
> (require '[clojure.string :as str])
>
> (defn map-to-query-string [m]
>   (str/join "&" (map (fn [[k v]] (str (name k) "=" v)) m)))
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View --http://corfield.org/
> World Singles, LLC. --http://worldsingles.com/
> Railo Technologies, Inc. --http://www.getrailo.com/

Brad

unread,
Aug 2, 2011, 8:24:46 AM8/2/11
to Clojure
Great. Encoding the parameters was the next thing to figure out.
Thank you.

On Aug 2, 12:51 am, Matjaz Gregoric <gre...@gmail.com> wrote:
> Depending on your input, you might also want to make sure to properly
> urlencode the keys and values.
> There is a function in hiccup that does what you want (including
> urlencoding):
>
> https://github.com/weavejester/hiccup/blob/10c3ebe175edc80eed1a0792ec...

Vinzent

unread,
Aug 4, 2011, 3:06:22 PM8/4/11
to Clojure
Also, you can use jaco's named routes to do this:
(defroute simple "/foo/bar")
(simple :baz "qux") => "/foo/bar?baz=qux"
Reply all
Reply to author
Forward
0 new messages