Holger wrote:
>>Maybe it would be useful to have a method similar to #sortedBy: in the
base image
Here are techniques I use for efficient sorting. Given that...
Sorting usually involves multiple attributes. Sorting needs to be fast.
Determining all the attributes in advance for each of the objects to be
compared would not be efficient. A general sorting framework should
allow for the sorting of dissimilar objects without crashing.
Here is an example of how I sort code models of GemKit:
GbcCode>><= other
| i a b |
i := 1.
[
(a := self sortableFieldAt: i) isNil ifTrue: [^true].
(b := other sortableFieldAt: i) isNil ifTrue: [^false].
a < b ifTrue: [^true].
b < a ifTrue: [^false].
(i := i + 1) < 1000
] whileTrue: [].
self error: '#sortableFieldAt: returned an unlikely number of
matches before returning nil'.
GbcCode>>sortableFieldAt: pos
^nil
GbcClassReference>>sortableFieldAt: pos
pos = 1 ifTrue: [^50]. "Order: namespaces, variables, classes,
methods"
pos = 2 ifTrue: [^self hierarchyName].
pos = 3 ifTrue: [^self lastSourceMagnitude].
^nil
GbcGsUser>>sortableFieldAt: pos
pos = 1 ifTrue: [^25]. "Order: namespaces, variables, classes,
methods"
pos = 2 ifTrue: [^self name].
pos = 3 ifTrue: [^self lastSourceMagnitude].
^nil
GbcMethod>>sortableFieldAt: pos
pos = 1 ifTrue: [^100]. "Order: namespaces, variables, classes,
methods"
pos = 2 ifTrue: [^self className].
pos = 3 ifTrue: [^self isMeta ifTrue: [50] ifFalse: [51]].
pos = 4 ifTrue: [^self selector].
pos = 5 ifTrue: [^self lastSourceMagnitude].
^nil
GbcNamespaceAlias>>sortableFieldAt: pos
pos = 1 ifTrue: [^20]. "Order: namespaces, variables, classes,
methods"
pos = 2 ifTrue: [^self name].
pos = 3 ifTrue: [^self lastSourceMagnitude].
^nil
GbcSharedVariable>>sortableFieldAt: pos
pos = 1 ifTrue: [^30]. "Order: namespaces, variables, classes,
methods"
pos = 2 ifTrue: [^self name].
pos = 3 ifTrue: [^self lastSourceMagnitude].
^nil
Now I just use #asSortedCollection to allow all the models to be
sequenced. The big thing is that it only incurs the cost of fetching
sort attributes when necessary for a comparison. Temporary objects are
not created for the sorting behavior.
In this implementation I returned a generality for the first field.
There are plenty of other ways it can be done for more generic use, but
this was the most efficient for my needs. It is simple, fast, and
flexible. You could for example change the code around to pass a
sortContext as a second argument (like if you wanted to sort by a
different attribute for a window).
Paul Baumann
--------------------------------------------------------
This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.
_______________________________________________
vwnc mailing list
vwnc@...
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc