There's java.util.LinkedHashSet: http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
Its iterator will preserve insertion order, but it will ignore duplicates when inserted. It has a number of disadvantages: * only available on clj-jvm * not a persistent data structure, with all the pain that brings * doesn't permit arbitrary iterator orders, only insertion order It would be an interesting exercise to reimplement Linkedhashset as a persistent data structure, implementing IPersistentSet and Seqable. Phil On Mar 24, 2012 1:29 PM, "mnicky" <markus.mas...@gmail.com> wrote: > Thanks for the explanations! > So is there a way to build a set or map that has sorting property > independent from the element lookup? > > On Friday, March 16, 2012 2:03:15 AM UTC+1, Alan Malloy wrote: >> >> And this is exactly as it should be. The sorted set has no way to >> compare items other than by your comparator. If it just arbitrarily >> decided to use = instead of checking that (zero? (compare x y)) it >> would not be using your comparator. >> >> Note also that the behavior of contains? is consistent with conj and >> disj: if the item is contained in the set, then conj will keep size >> the same and disj will decrease it; otherwise conj will increase the >> size and disj will leave it the same. >> >> On Mar 15, 3:39 pm, Stuart Campbell <stu...@harto.org> wrote: >> > Actually, sorted-map-by does behave the same way, but in your example >> you >> > tried to lookup a value instead of a key: >> > >> > user> (def m (sorted-map-by #(< (%1 0) (%2 0)) [1 :a] [2 :b])) >> > #'user/m >> > user> (get m [1 :foo]) >> > [2 :b] >> > >> > It looks like PersistentTreeMap.entryAt< >> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/P..<https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/P..>.>is >> >> > responsible for this behaviour. >> > >> > Regards, >> > Stuart >> > >> > On 13 March 2012 05:20, mnicky <markus.mas...@gmail.com> wrote: >> > >> > > It seems that when using the sorted set with my own comparator >> > > (sorted-set-by), >> > > the lookup via 'contains?' function is based only on the part of the >> items >> > > that participate in the ordering: >> > >> > > (contains? (sorted-set [1 :a] [2 :b]) [2 :c]) >> > > ;=> false >> > >> > > (contains? (sorted-set-by #(< (%1 0) (%2 0)) [1 :a] [2 :b]) [2 :c]) >> > > ;=> true >> > >> > > The documentation of 'sorted-set-by' says that the _whole_ items are >> keys: >> > >> > > (doc sorted-set-by) >> > > ; clojure.core/sorted-set-by >> > > ; ([comparator & keys]) >> > > ; Returns a new sorted set with supplied keys, using the supplied >> > > comparator. >> > > ; nil >> > >> > > So according to the documentation of 'contains?', it should do lookup >> > > based on the whole items, not just their parts used in the >> comparator: >> > >> > > (doc contains?) >> > > ; clojure.core/contains? >> > > ; ([coll key]) >> > > ; Returns true if key is present in the given collection, otherwise >> > > ; returns false. Note that for numerically indexed collections like >> > > ; vectors and Java arrays, this tests if the numeric key is within >> the >> > > ; range of indexes. 'contains?' operates constant or logarithmic >> time; >> > > ; it will not perform a linear search for a value. See also 'some'. >> > > ; nil >> > >> > > It's also worth noting that 'sorted-map-by' doesn't behave in this >> way: >> > >> > > (contains? (sorted-map-by #(< (%1 0) (%2 0)) [1 :a] [2 :b]) [2 :c]) >> > > ;=> false >> > >> > > Can this be a bug? If not, what's the reason behind this behavior? >> > >> > > -- Mnicky >> > >> > > -- >> > > 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+unsubscribe@googlegroups.com<clojure%2bunsubscr...@googlegroups.com> >> > > For more options, visit this group at >> > >http://groups.google.com/group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en> > > > On Friday, March 16, 2012 2:03:15 AM UTC+1, Alan Malloy wrote: >> >> And this is exactly as it should be. The sorted set has no way to >> compare items other than by your comparator. If it just arbitrarily >> decided to use = instead of checking that (zero? (compare x y)) it >> would not be using your comparator. >> >> Note also that the behavior of contains? is consistent with conj and >> disj: if the item is contained in the set, then conj will keep size >> the same and disj will decrease it; otherwise conj will increase the >> size and disj will leave it the same. >> >> On Mar 15, 3:39 pm, Stuart Campbell <stu...@harto.org> wrote: >> > Actually, sorted-map-by does behave the same way, but in your example >> you >> > tried to lookup a value instead of a key: >> > >> > user> (def m (sorted-map-by #(< (%1 0) (%2 0)) [1 :a] [2 :b])) >> > #'user/m >> > user> (get m [1 :foo]) >> > [2 :b] >> > >> > It looks like PersistentTreeMap.entryAt< >> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/P..<https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/P..>.>is >> >> > responsible for this behaviour. >> > >> > Regards, >> > Stuart >> > >> > On 13 March 2012 05:20, mnicky <markus.mas...@gmail.com> wrote: >> > >> > > It seems that when using the sorted set with my own comparator >> > > (sorted-set-by), >> > > the lookup via 'contains?' function is based only on the part of the >> items >> > > that participate in the ordering: >> > >> > > (contains? (sorted-set [1 :a] [2 :b]) [2 :c]) >> > > ;=> false >> > >> > > (contains? (sorted-set-by #(< (%1 0) (%2 0)) [1 :a] [2 :b]) [2 :c]) >> > > ;=> true >> > >> > > The documentation of 'sorted-set-by' says that the _whole_ items are >> keys: >> > >> > > (doc sorted-set-by) >> > > ; clojure.core/sorted-set-by >> > > ; ([comparator & keys]) >> > > ; Returns a new sorted set with supplied keys, using the supplied >> > > comparator. >> > > ; nil >> > >> > > So according to the documentation of 'contains?', it should do lookup >> > > based on the whole items, not just their parts used in the >> comparator: >> > >> > > (doc contains?) >> > > ; clojure.core/contains? >> > > ; ([coll key]) >> > > ; Returns true if key is present in the given collection, otherwise >> > > ; returns false. Note that for numerically indexed collections like >> > > ; vectors and Java arrays, this tests if the numeric key is within >> the >> > > ; range of indexes. 'contains?' operates constant or logarithmic >> time; >> > > ; it will not perform a linear search for a value. See also 'some'. >> > > ; nil >> > >> > > It's also worth noting that 'sorted-map-by' doesn't behave in this >> way: >> > >> > > (contains? (sorted-map-by #(< (%1 0) (%2 0)) [1 :a] [2 :b]) [2 :c]) >> > > ;=> false >> > >> > > Can this be a bug? If not, what's the reason behind this behavior? >> > >> > > -- Mnicky >> > >> > > -- >> > > 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+unsubscribe@googlegroups.com<clojure%2bunsubscr...@googlegroups.com> >> > > For more options, visit this group at >> > >http://groups.google.com/group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en> > > > On Friday, March 16, 2012 2:03:15 AM UTC+1, Alan Malloy wrote: >> >> And this is exactly as it should be. The sorted set has no way to >> compare items other than by your comparator. If it just arbitrarily >> decided to use = instead of checking that (zero? (compare x y)) it >> would not be using your comparator. >> >> Note also that the behavior of contains? is consistent with conj and >> disj: if the item is contained in the set, then conj will keep size >> the same and disj will decrease it; otherwise conj will increase the >> size and disj will leave it the same. >> >> On Mar 15, 3:39 pm, Stuart Campbell <stu...@harto.org> wrote: >> > Actually, sorted-map-by does behave the same way, but in your example >> you >> > tried to lookup a value instead of a key: >> > >> > user> (def m (sorted-map-by #(< (%1 0) (%2 0)) [1 :a] [2 :b])) >> > #'user/m >> > user> (get m [1 :foo]) >> > [2 :b] >> > >> > It looks like PersistentTreeMap.entryAt< >> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/P..<https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/P..>.>is >> >> > responsible for this behaviour. >> > >> > Regards, >> > Stuart >> > >> > On 13 March 2012 05:20, mnicky <markus.mas...@gmail.com> wrote: >> > >> > > It seems that when using the sorted set with my own comparator >> > > (sorted-set-by), >> > > the lookup via 'contains?' function is based only on the part of the >> items >> > > that participate in the ordering: >> > >> > > (contains? (sorted-set [1 :a] [2 :b]) [2 :c]) >> > > ;=> false >> > >> > > (contains? (sorted-set-by #(< (%1 0) (%2 0)) [1 :a] [2 :b]) [2 :c]) >> > > ;=> true >> > >> > > The documentation of 'sorted-set-by' says that the _whole_ items are >> keys: >> > >> > > (doc sorted-set-by) >> > > ; clojure.core/sorted-set-by >> > > ; ([comparator & keys]) >> > > ; Returns a new sorted set with supplied keys, using the supplied >> > > comparator. >> > > ; nil >> > >> > > So according to the documentation of 'contains?', it should do lookup >> > > based on the whole items, not just their parts used in the >> comparator: >> > >> > > (doc contains?) >> > > ; clojure.core/contains? >> > > ; ([coll key]) >> > > ; Returns true if key is present in the given collection, otherwise >> > > ; returns false. Note that for numerically indexed collections like >> > > ; vectors and Java arrays, this tests if the numeric key is within >> the >> > > ; range of indexes. 'contains?' operates constant or logarithmic >> time; >> > > ; it will not perform a linear search for a value. See also 'some'. >> > > ; nil >> > >> > > It's also worth noting that 'sorted-map-by' doesn't behave in this >> way: >> > >> > > (contains? (sorted-map-by #(< (%1 0) (%2 0)) [1 :a] [2 :b]) [2 :c]) >> > > ;=> false >> > >> > > Can this be a bug? If not, what's the reason behind this behavior? >> > >> > > -- Mnicky >> > >> > > -- >> > > 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+unsubscribe@googlegroups.com<clojure%2bunsubscr...@googlegroups.com> >> > > For more options, visit this group at >> > >http://groups.google.com/group/clojure?hl=en<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 -- 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