Dmitry Kakurin wrote: > I actually like your "tag them then group them" approach. > But what if the same record can have multiple tags? > E.g. :sales and :upgrades? >
Hmmm. the first way that occurred to me is just make your tagging function return a set: (defn record-types [x] (disj #{(when (is-sale? x) :sales) (when (is-upgrade? x) :upgrades) (when (is-demo? x) :demos)} nil)) So you'd then get groups like: {#{:sales :upgrades} [...] #{:sales} [...] #{:upgrades} [...]} But unfortunately it seems that because the group-by in clojure.contrib.seq-utils uses a sorted-map it can't have keys that are sets (as there's no ordering defined for sets). You could either use vectors instead of sets, or better yet lets just define reduce-by and group-by to use a hash-map instead: (defn reduce-by [grouper f val coll] (reduce (fn [m x] (let [group (grouper x)] (assoc m group (f (get m group val) x)))) {} coll)) (defn group-by [grouper coll] (reduce-by grouper conj [] coll)) This has the advantage that you can do things like intersections ("number of sales sales that were also upgrades"). If you don't care about intersections and just want the three :sales, :upgrades, and :demos lists, then I guess we start with 'for' to generate [tag record] pairs: (for [record (get-idata) type (record-types record)] [type record]) So if "data1" is both sales and upgrades then you'd get: ([:sales data1] [:upgrades data1] [:sales data2] [:demos data3] ...) We can then reduce-by grouped on the first value in the pair (the tag) and then transform the resulting maps to select just the second item in the pair (the record): (reduce-by first #(conj %1 (second %2)) [] (for [record (get-idata) type (record-types record)] [type record])) => {:sales [data1 data2 ... ], :upgrades [data1 data3 ...], :demos [data4 ...]} --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---