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

Reply via email to