When I saw the part about traversing an arbitrarily nested collection,
I immediately thought of clojure.walk (http://clojure.github.com/
clojure/clojure.walk-api.html). I ended up with this:
(use 'clojure.walk)
(defn all-vals [k coll]
(let [vals (atom [])
find-val (fn [form]
(if-let [val (k form)] (swap! vals conj val))
form)]
(prewalk find-val coll)
@vals))
user=> (all-vals :distance {:goat "al" :distance 35})
[35]
user=> (all-vals :distance [{:goat "al" :distance 35}
{:goat "paula" :distance 25}])
[35 25]
user=> (all-vals :distance [{:goat "al" :distance 35}
{:goat "paula" :distance 25 :other {:distance 99}}])
[35 25 99]
I wanted to use walk in a purely functional manner (instead of the
current approach of iteratively updating 'vals'). However, I was
unable to do this, given that the function passed in to prewalk needs
to preserve the structure of the nested collections. Hopefully
someone can find a way to use walk in a purely functional way here.
On Dec 5, 7:12 pm, Alex Baranosky <[email protected]>
wrote:
> Hi guys,
>
> I would like a function to be able to take an arbitrarily nested collection
> and return a sequence of all values of a given key, such as :name, that
> appears anywhere in the nested collection.
>
> Does anything like this already exist?
>
> Thanks for the help,
> Alex
--
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