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<
>> http​s://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<
>> http​s://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<
>> http​s://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

Reply via email to