Sorry to be so slow getting back. Because they are maps, and a set can contain many maps which contain identical key value pairs - I assume because although they do indeed have identical key value pairs they are nevertheless not the same map.
On Tuesday, 24 March 2015 21:55:05 UTC, Ben wrote: > > why not just accumulate the interested customers in a set rather than a > seq in the first place? > > On Tue, Mar 24, 2015 at 2:50 PM, Simon Brooke <stil...@googlemail.com > <javascript:>> wrote: > >> I'm rewriting a very odd e-commerce website I first wrote in 1996, for a >> friend. >> >> The website features categories, which are supposed to be arranged into >> an acyclic directed graph (actually there are currently cycles in the >> graph, but there shouldn't be, and that is not the problem I'm trying to >> solve here; assume there are not). Customers can register interest in a >> category or in several categories. When an item is added to the site, we >> want to email every customer who may be interested in that item; which is >> to say >> >> customers who are interested in the category to which the item has been >> added, and >> customers who are interested in the parent of that category, and >> so on recursively to the root of the graph. >> >> Now, I can recurse up the graph asking each category in turn for the >> customers interested in it; and by concatenating the lists, arrive at one >> list of all the interested customers. The problem is that if one customer >> has registered interest in both a category and its parent, he will appear >> on the composite list twice. I need to construct from this a list of >> records in which each customer appears only once, otherwise they'll receive >> duplicate emails, which no-one likes. >> >> My solution, which I give below, is to recurse across the composite list >> constructing a map whose keys are email addresses and whose values are the >> customer records as maps; and then to take the values of that map. It >> works, but it doesn't feel like idiomatic clojure: >> >> (defn map-by-key >> "From this `list-of-maps`, produce a map keyed on the values for this >> `key`" >> [list-of-maps key] >> (if (empty? list-of-maps) {} >> (let [record (first list-of-maps)] >> (merge {(record key) record} (map-by-key (rest list-of-maps) >> key))))) >> >> >> (defn interested-customers >> "Return a list of the customers interested in the category with this >> `category-id`. Recurses up the tree of categories; `path` is passed to >> protect against cycles in the tree (which shouldn't be there by are >> not impossible)" >> ([category-id] >> (vals (map-by-key (interested-customers category-id #{}) :email))) >> ([category-id path] >> (if (contains? path category-id) () >> (let >> [id (if (integer? category-id) category-id >> (Integer/valueOf (str category-id))) >> category (categories/fetch id) >> parent (:parent category) >> upstream (if (not (nil? parent)) (interested-customers parent >> (conj path id)) ()) >> interested (select schema/customer >> (with schema/category >> (where {:id id})))] >> (concat interested upstream))))) >> >> Can anyone re-express that in a more idiomatic form? >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > Ben Wolfson > "Human kind has used its intelligence to vary the flavour of drinks, which > may be sweet, aromatic, fermented or spirit-based. ... Family and social > life also offer numerous other occasions to consume drinks for pleasure." > [Larousse, "Drink" entry] > > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.