Is there a standard function transforming a map's vals

33 views
Skip to first unread message

samppi

unread,
Oct 10, 2009, 8:40:37 PM10/10/09
to Clojure
Is there a function in the standard libraries that's equivalent to
this:

(defn transform-map [pred a-map]
(into {} (map (comp pred val) a-map)))

(is (= {:a 4, :b 3}
(transform-map inc {:a 3, :b 2})))

It's not like I can't write this myself; I use this a lot, though, and
I'm wondering if it's somewhere in the core or contrib. (I searched,
but I couldn't find it, either.)

Sean Devlin

unread,
Oct 10, 2009, 11:48:11 PM10/10/09
to Clojure
The short answer is no.

This came up on the dev list here:

http://groups.google.com/group/clojure-dev/browse_thread/thread/4b20e40d83095c67#

Oh, and I'd write the function slightly differently

(defn transform-map [f a-map] ...)

The f implies a mapping operation. pred implies a filter operation.

samppi

unread,
Oct 11, 2009, 12:02:23 AM10/11/09
to Clojure
Oops, you're right; I was thinking about something else. And I have
another mistake in my function too—I meant:

(defn transform-map [f a-map]
(into {} (map #(vector (key %) (f (val %))) a-map)))

It's unfortunate that it's not in any standard library yet. I've used
this function in every single Clojure program that I've written. Ah,
well.

On Oct 10, 8:48 pm, Sean Devlin <francoisdev...@gmail.com> wrote:
> The short answer is no.
>
> This came up on the dev list here:
>
> http://groups.google.com/group/clojure-dev/browse_thread/thread/4b20e...

Daniel Werner

unread,
Oct 11, 2009, 3:17:22 PM10/11/09
to Clojure
On Oct 11, 6:02 am, samppi <rbysam...@gmail.com> wrote:
> Oops, you're right; I was thinking about something else. And I have
> another mistake in my function too—I meant:
>
> (defn transform-map [f a-map]
> (into {} (map #(vector (key %) (f (val %))) a-map)))
>
> It's unfortunate that it's not in any standard library yet. I've used
> this function in every single Clojure program that I've written. Ah,
> well.

Konrad Hinsen's generic functor multimethod seems to do exactly what
you want:

user=> (use 'clojure.contrib.generic.functor)
nil
user=> (fmap inc {:a 4, :b 3})
{:a 5, :b 4}

Actually it is not limited to maps:

user=> (fmap inc [4 3])
[5 4]

It's just too easy to miss beautiful and useful gems like this in the
depths of clojure.contrib.

Stuart Sierra

unread,
Oct 11, 2009, 9:19:54 PM10/11/09
to Clojure
On Oct 10, 8:40 pm, samppi <rbysam...@gmail.com> wrote:
> (defn transform-map [f a-map]
> (into {} (map #(vector (key %) (f (val %))) a-map)))

I always find map transformations easier to write with reduce:

(defn transform-map [f mm]
(reduce (fn [m [k v]] (assoc m k (f v))) {} mm))

-SS

John Harrop

unread,
Oct 12, 2009, 1:54:06 AM10/12/09
to clo...@googlegroups.com
Agreed. That's why I may create a kind of "mind map" of that library (and throw in clojure.core) that can find functions by, well, function. So all the stuff for manipulating maps can be found, or all the stuff for file I/O, etc. 

Christophe Grand

unread,
Oct 12, 2009, 5:33:26 AM10/12/09
to clo...@googlegroups.com
Note that if you're only interested in using the resulting map as a function, (comp f map) works well (you can throw memoize in for good measure).
--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)
Reply all
Reply to author
Forward
0 new messages