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.