On Sun, Oct 3, 2010 at 3:32 AM, Alan <a...@malloys.org> wrote: > I've got a collection of unique objects, and I need to partition them > into sets. That part's easy enough, but I need to have both of the > following be efficient, and preferably easy: > - Given an object, determine what set it's in > - List all the objects in a given set > > In an imperative language this would be fairly simple: create some > empty sets, then iterate over all objects; at each step add the object > to a set, and adjust the object's "parent" pointer to point at the set > it's in. > > But in a functional, immutable context the circularity involved seems > to make this really inconvenient: if I create the set first then it > can't point to the object, and if I create the object first it can't > point at its set. > > I could construct all the objects and have a single "global" map, with > mappings for both set-id=>[objects] and object=>set-id, but this seems > kinda gross and obscures what is actually meant (objects belong to > sets) with implementation (integers/keywords mapping to groups of > objects, and objects mapping to integers). > > Likewise, I could use some kind of mutable refs in part of the > process, but (a) that feels like giving up, and (b) since I'll be > modifying these sets recursively and backtracking to "past" states it > would add a tremendous amount of bookkeeping to undo changes. > > This seems like a pretty common problem, so I'm sure some clever > Clojure coder out there has already solved it; what am I missing? >
This is a topic that comes up periodically. I've wondered this myself and recently realized that clojure.set does deal with some of these issues. (ns db (:use clojure.set)) (def animals #{{:name "penguin" :type "bird"} {:name "dolphin" :type "mammal"} {:name "lion" :type "mammal"} {:name "ant" :type "insect"}}) ;; group the animals into sets (def by-type (index animals [:type])) ;; get all birds who's first name start with the character 'p' (select (fn [{[c] :name}] (= c \p)) (by-type {:type "bird"})) Is something about this that doesn't work for your problem? -- 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