Hi Christophe Grand Yea true I kind of got confused .. thanks for the solution.. Sunil
On Wed, Nov 17, 2010 at 1:12 PM, Christophe Grand <christo...@cgrand.net>wrote: > On Wednesday, November 17, 2010, Sunil S Nandihalli > <sunil.nandiha...@gmail.com> wrote: > > Regarding your bimap implementation, in terms of complexity, I feel, it > will be linear in the number of elements, when accessing the pair via the > value .. Is that true? > > No I use two maps and rmap is O(1) so rmap+get is O(log32 n) like a > direct get. What may confuse you is that only the direct map is > hinted. The reverse map doesn't need to: no interop calls on it while > it is in reverse position. > > > On Tue, Nov 16, 2010 at 2:36 PM, Christophe Grand <christo...@cgrand.net> > wrote: > > > > > > You can implement your own, prettu easily with deftype. > > However it can be tedious to track every methods, so we need a repl > helper function to scaffold the code for us. > > > > (defn scaffold [iface] > > (doseq [[iface methods] (->> iface .getMethods > > (map #(vector (.getName (.getDeclaringClass > %)) > > (symbol (.getName %)) > > (count (.getParameterTypes %)))) > > (group-by first))] > > (println (str " " iface)) > > (doseq [[_ name argcount] methods] > > (println > > (str " " > > (list name (into ['this] (take argcount (repeatedly > gensym))))))))) > > > > user=> (scaffold clojure.lang.IPersistentMap) > > clojure.lang.IPersistentMap > > (assoc [this G__441 G__442]) > > (without [this G__443]) > > (assocEx [this G__444 G__445]) > > java.lang.Iterable > > (iterator [this]) > > clojure.lang.Associative > > (containsKey [this G__446]) > > (assoc [this G__447 G__448]) > > (entryAt [this G__449]) > > clojure.lang.IPersistentCollection > > (count [this]) > > (cons [this G__450]) > > (empty [this]) > > (equiv [this G__451]) > > clojure.lang.Seqable > > (seq [this]) > > clojure.lang.ILookup > > (valAt [this G__452 G__453]) > > (valAt [this G__454]) > > clojure.lang.Counted > > (count [this]) > > nil > > > > Now you need to remove the duplicates (count and assoc), wrap everything > in a deftype form and implement it: > > (including a new protocol fn to reverse a bidi map) > > > > (defprotocol ReversibleMap > > (rmap [m])) > > > > (defn- rdissoc [d r v] > > (if-let [[_ k] (find r v)] (dissoc d k) d)) > > > > (deftype Bimap [^clojure.lang.IPersistentMap direct reverse] > > Object > > (hashCode [x] > > (.hashCode direct)) > > (equals [x y] > > (.equals direct y)) > > clojure.lang.IPersistentMap > > (without [this k] > > (Bimap. > > (dissoc direct k) > > (rdissoc reverse direct k))) > > (assocEx [this k v] > > (if (or (contains? direct k) (contains? reverse v)) > > (throw (Exception. "Key or value already present")) > > (assoc this k v))) > > java.lang.Iterable > > (iterator [this] > > (.iterator direct)) > > clojure.lang.Associative > > (assoc [this k v] > > (Bimap. > > (assoc (rdissoc direct reverse v) k v) > > (assoc (rdissoc reverse direct k) v k))) > > (containsKey [this k] > > (contains? direct k)) > > (entryAt [this k] > > (find direct k)) > > clojure.lang.IPersistentCollection > > (cons [this x] > > (if-let [[k v] (and (vector? x) x)] > > (assoc this k v) > > (reduce (fn [m [k v]] (assoc m k v)) this x))) > > (empty [this] > > (.empty direct)) > > (equiv [this x] > > (.equiv direct x)) > > clojure.lang.Seqable > > (seq [this] > > (seq direct)) > > clojure.lang.ILookup > > (valAt [this k else] > > (direct k else)) > > (valAt [this k] > > (direct k)) > > clojure.lang.Counted > > (count [this] > > (count direct)) > > ReversibleMap > > (rmap [this] > > (Bimap. reverse direct))) > > > > (defn bimap [& kvs] > > (reduce (fn [m [k v]] (assoc m k v)) (Bimap. {} {}) (partition 2 kvs))) > > > > Some quick tests: > > user=> (assoc (bimap :a 1 :b 2) [:c 3] [:d 4] [:e 5]) > > {[:e 5] nil, [:c 3] [:d 4], :b 2, :a 1} > > user=> (assoc (bimap :a 1 :b 2) :c 3 :d 4 :e 5) > > {:e 5, :d 4, :c 3, :b 2, :a 1} > > user=> (assoc (bimap :a 1 :b 2) :c 3 :d 2 :e 5) > > {:e 5, :d 2, :c 3, :a 1} > > user=> (dissoc *1 :d) > > {:e 5, :c 3, :a 1} > > user=> (rmap *1) > > {5 :e, 3 :c, 1 :a} > > user=> (assoc *1 2 :c) > > {2 :c, 5 :e, 1 :a} > > > > hth, > > > > Christophe > > > > > > > > > > > > On Tue, Nov 16, 2010 at 8:16 AM, Sunil S Nandihalli < > sunil.nandiha...@gmail.com> wrote: > > > > > > > > A bimap is a map where each elements of the pair can be used as key to > access it.. > > Sunil. > > > > On Tue, Nov 16, 2010 at 12:44 PM, Sunil S Nandihalli < > sunil.nandiha...@gmail.com> wrote: > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.cgrand.net/ (en) > > -- > 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<clojure%2bunsubscr...@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 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