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.

Reply via email to