Interesting problem. This is my (first iteration) of a solution:
--8<---------------cut here---------------start------------->8---
(defn select-in [m keyseq]
(loop [acc {} [k & ks] (seq keyseq)]
(if k
(recur
(if (sequential? k)
(let [[k ks] k]
(assoc acc k
(select-in (get m k) ks)))
(assoc acc k (get m k)))
ks)
acc)))
--8<---------------cut here---------------end--------------->8---
The `keyseq' parameter uses seqs instead of the maps in your example,
but I think the usage is fairly convenient:
--8<---------------cut here---------------start------------->8---
(select-in my-map [:name
:email
[:address [:city
:state]]
[:spouse [:name
[:address [:city
:state]]]]])
--8<---------------cut here---------------end--------------->8---
One thing to notice is that this function doesn't work as intended on
maps with seqs as keys. It's also not tail-recursive but maps nested so
deep that this becomes a problem are a problem by itself.
Baishampayan Ghose <[email protected]> writes:
> Hi,
>
> I have a problem wherein I need to select subsets of a given map;
> think about select-keys, but with arbitrary nesting.
>
> For example, consider this map -
>
> (def my-map {:name "John Doe"
> :email "[email protected]"
> :address {:house "42"
> :street "Moon St."
> :city "San Francisco"
> :state "CA"
> :zip 76509
> :mobile "+188888888"}
> :ssn "123456"
> :spouse {:name "Jane Doe"
> :ssn "654321"
> :relation :wife
> :address {:house "42"
> :street "Moon St."
> :city "Atlanta"
> :state "GA"
> :zip 76509
> :mobile "+188888888"}}})
>
> From the above map, I want to extract this sub-map -
>
> {:spouse {:name "Jane Doe", :address {:state "GA", :city "Atlanta"}},
> :name "John Doe",
> :email "[email protected]",
> :address {:state "CA", :city "San Francisco"}}
>
> What would be a good way to express this sub-map so that I can pass it
> on to a function?
>
> I am thinking about something like this -
>
> [:name :email {:address [:city :state]} {:spouse [:name {:address
> [:city :state]}]}]
>
> Example implementations are also welcome.
>
> Regards,
> BG
>
> --
> Baishampayan Ghose
> b.ghose at gmail.com
--
Moritz Ulrich
--
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