Does a standard function exist that acts like assoc except it applies fns to vals

0 views
Skip to first unread message

samppi

unread,
Nov 22, 2009, 4:32:14 PM11/22/09
to Clojure
Does a function that does this:
(vary coll :x fn-x, :y fn-y)
; Equivalent to (assoc coll :x (fn-x (:x coll)), :y (fn-y (:y
coll)))
exist in the core or contrib APIs?

I'm surprised that I can't find any. It's a very natural extension of
assoc. But if there really isn't any, is the code below the best/most-
idiomatic/most-efficient way to implement such a function?

(defn vary [coll & keys-and-fns]
(let [fn-map (apply arrray-map keys-and-fns)
keys-and-vals (mapcat #((val %) (get coll (key %))) fn-map)]
(apply assoc-args coll keys-and-vals)))

John Harrop

unread,
Nov 22, 2009, 4:38:56 PM11/22/09
to clo...@googlegroups.com
On Sun, Nov 22, 2009 at 4:32 PM, samppi <rbys...@gmail.com> wrote:
Does a function that does this:
 (vary coll :x fn-x, :y fn-y)
 ; Equivalent to (assoc coll :x (fn-x (:x coll)), :y (fn-y (:y
coll)))
exist in the core or contrib APIs?

I'm surprised that I can't find any. It's a very natural extension of
assoc.

There's update-in, which is like what you want but for assoc-in, but oddly no plain update analogously to plain assoc. I'd use update-in. 

samppi

unread,
Nov 22, 2009, 5:07:32 PM11/22/09
to Clojure
Ah, update-in is exactly what I need. Excellent, thank you.

On Nov 22, 2:38 pm, John Harrop <jharrop...@gmail.com> wrote:

Meikel Brandmeyer

unread,
Nov 22, 2009, 5:04:47 PM11/22/09
to clo...@googlegroups.com
Hi,

Am 22.11.2009 um 22:32 schrieb samppi:

> (defn vary [coll & keys-and-fns]
> (let [fn-map (apply arrray-map keys-and-fns)
> keys-and-vals (mapcat #((val %) (get coll (key %))) fn-map)]
> (apply assoc-args coll keys-and-vals)))

As Jon said: update-in.

(-> coll
(update-in [:x] fn-x)
(update-in [:y] fn-y))

Sincerely
Meikel

Reply all
Reply to author
Forward
0 new messages