(use '[clojure.contrib.generic.functor :only (fmap)])

(defn update-in-wildcard
  "Like update-in, but with :* as a wildcard matcher"
  ([m [k & ks] f & args]
   (condp = [(= k :*) (boolean ks)]
     [true true] (fmap #(apply update-in-wildcard % ks f args) m)
     [true false] (fmap f m)
     [false true] (assoc m k (apply update-in-wildcard (get m k) ks f
args))
     [false false] (assoc m k (apply f (get m k) args)))))

This seems to do what you want.  I had a similar situation but hadn't
thought of abstracting it out in this way until I read your post.  The
condp is somewhat ugly, but I didn't want nested if's checking for the
same condition.  If anyone can think of a nicer way of doing the
conditional, let me know.



On Apr 10, 11:32 am, Ozzi Lee <ozzi...@gmail.com> wrote:
> I have a structure of nested Maps and Vectors as follows:
>
> (def document
>      {:sections
>       [{:items
>         [{:quantity 1}
>          {:quantity 2}]}
>        {:items
>         [{:quantity 3}
>          {:quantity 4}]}]})
>
> The document has a vector of sections (one, in this case), each
> section has a vector of items (two, here).
>
> I want to increment the quantity of every item in every section. The
> cleanest solution I've found this far is as follows:
>
> (defn update-item [item]
>   (update-in item [:quantity] inc))
>
> (defn update-section [section]
>   (update-in section [:items] (partial map update-item)))
>
> (update-in document [:sections]
>         (partial map update-section))
>
> I'm not concerned about map turning vectors into seqs.
>
> If update-in supported some kind of wildcard, I could write this:
>
>  (update-in document [:sections * :items * :quantity] inc)
>
> Where * is a wildcard, meaning "any key".
>
> Does the wildcard idea have any merit? Is there a better way to go
> about this?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to