Что должна возвращать функция сравнения
Что проверяют
Знаете ли вы контракт сортировки в Swift и не тащите ли привычку из языков, где компаратор возвращает число. В Swift это булев предикат, и от того, какой именно, зависит, отсортируется коллекция корректно или сломается.
Как отвечать
Методы sorted(by:) и sort(by:) принимают замыкание вида (Element, Element) -> Bool, которое отвечает на один вопрос: должен ли первый аргумент идти строго раньше второго. Значит true только при строгом «меньше», а для равных элементов обязателен false.
let byAge = people.sorted { $0.age < $1.age }Трёхзначное сравнение в экосистеме тоже есть, но в другом месте: методы Foundation вроде compare(_:) возвращают ComparisonResult со значениями .orderedAscending, .orderedSame, .orderedDescending, а не целое число. Для собственного типа правильный путь это Comparable: реализуете <, бесплатно получаете sorted() без замыкания, min(), max() и диапазоны. Помните, что Comparable наследует Equatable и оператор < должен быть согласован с ==. Для Set и ключей словаря нужен не компаратор, а Hashable: равные объекты обязаны давать одинаковый хеш.
Где спотыкаются
Возвращают результат нестрогого сравнения, то есть <=. Предикат перестаёт задавать строгий порядок, и поведение сортировки становится неопределённым: перемешанный результат или аварийное завершение на большом массиве. Условие должно быть строгим.
Рассчитывают на стабильность. Сортировка в стандартной библиотеке не гарантирует сохранение исходного порядка равных элементов, поэтому список на экране может дёргаться при перерисовке. Нужна предсказуемость, добавьте второй ключ сравнения, например идентификатор.
Сравнивают Double, забыв про NaN: любое сравнение с ним даёт false, и порядок разваливается. То же с текстом: < для строк это порядок по скалярам Unicode, регистр и локаль он не учитывает, для списка на экране нужен localizedStandardCompare.