When thinking about things functionally, it's useful to start from a
basic case, and then work upward.

For instance, we could start off by only transforming one key:

  (defn expand-map-key [m k]
    (for [v (.split (m k) " ")]
      {k v}))

So:

  user=> (expand-map-key m :animal)
  ({:animal "dog"} {:animal "cat"} {:animal "bird"})

The problem now becomes: how can we apply expand-map-key to each
value, and then combine the results?

First apply the function to each value:

  (for [k (keys m)]
    (expand-map-key m k))

This gets us something like:

  (({:animal "dog"} {:animal "cat"} {:animal "bird"})
   ({:sound "woof"} {:sound "meow} {:sound "chirp"})
   ...)

Next we need to merge the first entries into one map, the second
entries into another map, and so forth. This is usually known as
zipping. We can use apply and map for this:

  (apply map merge m)

So in total, your function will look like:

  (apply map merge
    (for [k (keys m)]
      (expand-map key m k)))

Or perhaps we don't even need expand-map-key to be a separate
function:

  (apply map merge
    (for [k (keys m)]
      (for [v (.split (m k) " ")]
        {k v}))))

One word of warning: I don't currently have access to a Clojure
interpreter, so the above may be not be quite right. If it isn't
right, I hope the line of though of how I got there is of some use.

- James

On Mar 5, 7:07 pm, Base <basselh...@gmail.com> wrote:
> Hi all -
>
> I am trying to transofrm a data structure and am kind of stuck.
>
> I currently have a list of maps
>
> ( {:animal "dog cat bird" :sound "woof meow chirp" :number-of-feet "4
> 4 2"}
>   {:animal "horse" :sound "neeeee" :number-of-feet "4"}
>   {:animal "wolf pig" :sound "howl oink":number-of-feet "4 4"} )
>
> and want to trasform it to:
>
> (
>   ({:animal "dog" :sound "woof" :number-of-feet "4" }
>    {:animal "cat" :sound "meow" :number-of-feet "4"}
>    {:animal "bird" :sound "chirp" :number-of-feet "2"})
>
>   ({:animal "horse":sound "neeee" :number-of-feet "4"})
>
>   ({:animal "wolf" :sound "howl" :number-of-feet "4"}
>    {:animal "pig" :sound "oink" :number-of-feet "4"})
> )
>
> *spacing added for clarity*
>
> I have tried a few goofy attempts at this that were somewhat
> successful. but what I don't like is that most of my attempts (which i
> am kind of embarrassed to post) end up looking very un-clojuresque,
> and much more imperative looking...and we all know there is a better,
> more idiomatic way...
>
> any help is (as always) most appreciated.
>
> thanks
>
> base

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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