sort возвращает новый отсортированный массив, по умолчанию сравнивая элементы через <=>. Блок сравнения должен вернуть отрицательное число, ноль или положительное число. Array#sort! меняет исходный массив. Для сортировки по вычисляемому ключу удобен sort_by. Стабильный порядок элементов с одинаковыми ключами по умолчанию не гарантируется.
Как работает метод sort в Ruby?
Оператор <=>, собственный порядок, sort_by и изменяющие массив методы. Что учитывать при равных ключах.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
sort возвращает массив с упорядоченными элементами, не переставляя элементы исходного массива. По умолчанию используется оператор <=>:
numbers = [3, 1, 4, 1]
p numbers.sort # [1, 1, 3, 4]
p numbers # [3, 1, 4, 1]
p numbers.sort { |a, b| b <=> a } # [4, 3, 1, 1]
Блок получает два элемента. Отрицательный результат ставит первый раньше второго, положительный — позже, ноль означает равенство для данного сравнения. Возвращать true или false вместо числа нельзя. Если элементы несравнимы и <=> возвращает nil, сортировка может завершиться ошибкой.
Для именованного ключа запись обычно проще через sort_by:
people = [{ name: "Anna", age: 30 }, { name: "Boris", age: 25 }]
sorted = people.sort_by { |person| [person[:age], person[:name]] }
Здесь имя — явный дополнительный критерий при равном возрасте. sort_by вычисляет ключи перед сравнением; он удобен для дорогого извлечения ключа, но не обязан быть быстрее во всех случаях.
Методы массива sort! и sort_by! изменяют сам массив. Не следует рассчитывать на сохранение взаимного порядка элементов с равными ключами: если он важен, добавьте исходный индекс как последний критерий. Строковое сравнение также не равно автоматически правилам алфавитной сортировки выбранного языка. Array#sort, Enumerable#sort_by.