On Sun, Aug 30, 2009 at 4:14 PM, kyle smith <[email protected]> wrote:
>
> I wrote this based on assoc-in. If anyone thinks this should be in
> core or contrib, feel free to use it.
>
> (defn assoc-in-by
> "'Updates' a value in a nested associative structure, where ks is a
> sequence of keys and (f v) is the new value and returns a new nested
> structure.
> If any levels do not exist, hash-maps will be created."
> [m [k & ks] f]
> (if ks
> (assoc m k (assoc-in-by (get m k) ks f))
> (assoc m k (f (get m k)))))
Nifty and seems to work. Here's a little demo:
user=> (assoc-in-by nil [:a :b :c] #(if (nil? %) 1 (inc %)))
{:a {:b {:c 1}}}
user=> (assoc-in-by *1 [:a :b :c] #(if (nil? %) 1 (inc %)))
{:a {:b {:c 2}}}
user=> (assoc-in-by *1 [:a :b :c] #(if (nil? %) 1 (inc %)))
{:a {:b {:c 3}}}
user=> (assoc-in-by *1 [:a :b :c] #(if (nil? %) 1 (inc %)))
{:a {:b {:c 4}}}
which has a counter incrementing.
And it's swap! and alter!-compatible:
(swap! foo assoc-in-by [:a :b :c] #(bar % baz))
Maybe a version that takes more args?
(defn assoc-in-by
"'Updates' a value in a nested associative structure, where ks is a
sequence of keys and (f v) is the new value and returns a new nested
structure.
If any levels do not exist, hash-maps will be created."
([m [k & ks] f]
(if ks
(assoc m k (assoc-in-by (get m k) ks f))
(assoc m k (f (get m k)))))
([m [k & ks] f args]
(if ks
(assoc m k (assoc-in-by (get m k) ks f args))
(assoc m k (apply f (get m k) args)))))
which simplifies the swap! example to:
(swap! foo assoc-in-by [:a :b :c] bar baz)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---