Как работает метод sort в Ruby?

Оператор <=>, собственный порядок, sort_by и изменяющие массив методы. Что учитывать при равных ключах.

Короткий ответ

Что ответить на собеседовании

sort возвращает новый отсортированный массив, по умолчанию сравнивая элементы через <=>. Блок сравнения должен вернуть отрицательное число, ноль или положительное число. Array#sort! меняет исходный массив. Для сортировки по вычисляемому ключу удобен 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.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку