Map from generator?

2 views
Skip to first unread message

Conrad

unread,
Feb 4, 2009, 10:36:35 PM2/4/09
to Clojure
It is useful to build a map from a list of keys and a value generator
function. Of Course, such a function is easy to write:

(defn genmap [keys fun]
(zipmap keys (map fun keys)))

In fact, it seems so useful that it must be in the standard API
somewhere, but I can't find it... did I miss it somewhere, or was I
right to create my own? Please let me know if I'm reinventing the
wheel.

Thanks!

Conrad Barski

Rich Hickey

unread,
Feb 5, 2009, 7:33:49 AM2/5/09
to Clojure
It does seem useful, although the zipmap call is already concise.

I wonder if this is a frequently reinvented wheel.

Rich

Mark McGranaghan

unread,
Feb 5, 2009, 7:46:30 AM2/5/09
to clo...@googlegroups.com
I frequently use a more general version of this function that reduces
a seq to a map, mapping each element in the seq to a [key value] pair
for the map. I use this in several different libs:

(defn mash
"Reduce a seq-able to a map. The given fn should return a 2-element tuple
representing a key and value in the new map."
[f coll]
(reduce
(fn [memo elem]
(let [[k v] (f elem)]
(assoc memo k v)))
{} coll))

Where "mash" comes from map + hash.

(mash (fn [elem] [(+ 1 elem) (+ 2 elem)]) (list 1 2 3))
=> {4 5, 3 4, 2 3}

You could also use into:

(into {} (map (fn [elem] [(+ 1 elem) (+ 2 elem)]) (list 1 2 3)))
=> {4 5, 3 4, 2 3}

- Mark

Albert Cardona

unread,
Feb 6, 2009, 4:47:32 AM2/6/09
to clo...@googlegroups.com


I had an almost identical (if less elegant) function to "genmap"
as well in my files. Adding it to core would be nice.

Albert

--
Albert Cardona
http://albert.rierol.net

Jason Wolfe

unread,
Feb 6, 2009, 1:04:03 PM2/6/09
to Clojure
> (defn mash
>   "Reduce a seq-able to a map. The given fn should return a 2-element tuple
>   representing a key and value in the new map."
>   [f coll]
>   (reduce
>     (fn [memo elem]
>       (let [[k v] (f elem)]
>         (assoc memo k v)))
>     {} coll))

I called this "map-map" in my utilities. Mine was even a bit more
general, in that it could take multiple collections like "map". This
allowed you to say thinks like

(map-map vector s (iterate inc 0))

to get a map from elements of s to indices.

Then Chouser pointed out [1] that map-map is equivalent to just

(into {} (map f coll1 coll2 ...))

[1] http://groups.google.com/group/clojure/browse_thread/thread/134642cc76de17f7/b93b74fa4a6806cd?hl=en&q=utilities&lnk=ol&

I still kind of like map-map, although I'm not sure if it's really any
better than the idiom Chouser gave. YMMV, but I'm pretty sure the
consensus was that map-map didn't belong in core, or probably even
contrib.

-Jason
Reply all
Reply to author
Forward
0 new messages