On Wed, 15 Sep 2010 11:48:09 -0700 Michael Ossareh <ossa...@gmail.com> 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 <m...@mired.org> 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 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