Smalltalk: сортировка коллекции по двум критериям

Как отсортировать коллекцию по двум критериям в Cincom VisualWorks?

Пример: у меня есть OrderedCollection, которая содержит людей, и хочу новую коллекцию, которая сортирует людей сначала по возрасту, а затем, если возраст совпадает, сортирует людей по имени.

Надеюсь, вы понимаете мой английский! Спасибо..

4 ответа

Решение

Код Шона в порядке, но я предпочитаю, чтобы он был написан таким образом, который более показателен и немного более эффективен:

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

Идея состоит в том, что блок сортировки должен отвечать true, если элемент a сортирует перед товаром b, Учитывая два ключа, элемент сортируется перед другим элементом, если используется его первичный ключ (age) меньше или первичный ключ такой же, а вторичный ключ (name) меньше.

Это переводит непосредственно в приведенный выше код и может быть легко расширен до третьего или более критериев сортировки (например, либо вторичный ключ меньше, либо он такой же, а третичный ключ меньше).

Трэвис Григгс реализовал интересный способ сделать этот вид намного более кратким способом. Он опубликовал свою работу как TAG-SortFunctions в публичном репозитории Cincom, и я считаю, что она была интегрирована в следующую версию VisualWorks. См. Его сообщение в блоге на тему и продолжение для деталей. Используя этот пакет, вы просто напишите что-то вроде этого (не проверено):

люди сортируют: #age sortUp, #name sortUp

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

То, что сказал Рэнди, но оно интегрировано в VisualWorks 7.8, и синтаксис будет aCollection asSortedCollection: #age по возрастанию, #name по убыванию

где вы также можете использовать sort: или что-нибудь еще, что заняло бы sortBlock.

Другие вопросы по тегам