On Wed, 15 Sep 2010 11:48:09 -0700
Michael Ossareh <[email protected]> wrote:
> Hi Guys,
>
> One of the things that has struck me about clojure, by virtue of being
> a lisp, is the concision of the code - I really find it very
> attractive. However yesterday I found something that I couldn't work
> out how to do in a concise manner. Clearly commenting the code was a
> priority once I got it working, however I'd like to ensure I'm doing
> this correctly.
>
> Much of my functional experience comes from JS and dealing with the
> immutability of our data structures is a very interesting learning
> process.
>
> I have a map (a sorted map) which maps an int to a map. The inner map
> contains a vector of data to which I want to conj elements into.
>
>
> { 0 {:title "some str"
> :meetings [{ ... meeting data ... }
> { ... meeting data ... }
> { ... meeting data ...}]}
>
> 1 {:title "some other str"
> :meetings [{ ... meeting data ... }
> { ... meeting data ... }
> { ... meeting data ...}]}
>
> .....
>
> n {:title "some n str"
> :meetings [{ ... meeting data ... }
> { ... meeting data ... }
> { ... meeting data ...}]}}
>
>
> In JS I'd have a loop which looks somewhat like this (assume the data
> above is called storedData and that newData has the data which I wish
> to insert into storedData);
>
> newData.forEach(function(data) {
>
> var key = .... ;
>
> if (!storedData[key])
> storedData[key] = {title: "title"}, meetings:[]}
>
> storedData[key].meetings.push(data) ;
>
> })
>
> In clj, I've ended up with something along the lines of the following
> (edited from what I have in my code base to match the JS example
> above):
>
> (loop [data (sorted-map)
> collection newData
> meeting (first collection)]
>
> (def key ( .... ))
As a general rule, def should only be used at the top level. You
probably want (let [key ...] (if ...) here.
> (if (not (nil? (next collection)
Minor nit: (not (nil? X)) is better spelled (seq? X))
And you seem to be missing a close paren or two here.
> (recur (cond (not (nil? (data key)))
>
> (assoc data key
> (assoc (data key)
> :meetings
> (conj ((data key) :meetings) meeting)))
>
> (true? true)
> (conj data [key {:title "some str" :meetings [meeting]}])))
>
> data))
>
>
> The middle section, with the assoc(es) and conj, just doesn't read as
> nicely as the rest of my clojure. Is this a symptom of my data
> structure or is there a more concise way to conj my data into these
> inner vectors?
That's actually a standard idiom, except you missed the assoc-in and
get-in functions:
(assoc-in data key :meetings (conj (get-in data key :meetings) meeting)
Should do what you want.
> Also, as a secondary concern, I read on here a while ago that when you
> find yourself typing "((" it's a sign of an issue - how, given the
> data structure I've to work with, woud you access the title of a value
> if not using that "((" syntax, i.e. ((data key) :title)?
I'm not sure where that came from, bug get-in and assoc-in solve that
as well.
<mike
--
Mike Meyer <[email protected]> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
--
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