Question

How can I sort a collection by two criteria in Cincom VisualWorks?

Example: I have an OrderedCollection that contains persons, and want a new collection that sort the persons first by age, and then if the age is the same sort the persons by name.

Hope you can understand my english! Thanks..

Was it helpful?

Solution

Sean's code is fine, but I prefer it written this way, which is more intention-revealing and slightly more efficient:

people sort: [ :a :b |
    a age < b age
        or: [a age = b age and: [ a name < b name ] ]

The idea is that the sort block should answer true if item a sorts before item b. With two keys to consider, an item sorts before another item if either its primary key (age) is less, or the primary key is the same, and the secondary key (name) is less.

This translate directly into the code above, and can be easily extended to a third or more sort criteria (e.g., either the secondary key is less, or it is the same and the tertiary key is less).

OTHER TIPS

Travis Griggs implemented an interesting way of doing this kind of sort in a much more succinct way. He published his work as TAG-SortFunctions in the Cincom Public Repository, and I believe it has been integrated into the next release of VisualWorks. See his blog post on the topic and the followup for details. Using this package, you would simply write something like this (untested):

people sort: #age sortUp, #name sortUp

people sort: [ :a :b |
    a age = b age
        ifTrue: [ a name < b name ]
        ifFalse: [ a age < b age ] ]

What Randy said, but it is integrated in VisualWorks 7.8, and the syntax would be aCollection asSortedCollection: #age ascending, #name descending

where you can also use sort:, or anything else that would take a sortBlock.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top