Сортировка - одна из фундаментальных операций при работе с коллекциями. Ruby предоставляет богатый набор методов для сортировки массивов и хэшей, каждый из которых имеет свои особенности.
numbers = [3, 1, 4, 2]
# sort - возвращает новый отсортированный массив
numbers.sort #=> [1, 2, 3, 4]
# sort! - сортирует исходный массив
numbers.sort! # теперь numbers == [1, 2, 3, 4]
# sort_by - сортировка по результату блока
['apple', 'pear', 'banana'].sort_by { |word| word.length }
#=> ["pear", "apple", "banana"]
# reverse после sort
[3, 1, 4, 2].sort.reverse #=> [4, 3, 2, 1]
# sort с отрицательным сравнением
[3, 1, 4, 2].sort { |a, b| b <=> a } #=> [4, 3, 2, 1]
# Сортировка по нескольким критериям
users = [
{name: 'Alice', age: 25},
{name: 'Bob', age: 30},
{name: 'Alice', age: 20}
]
users.sort_by { |u| [u[:name], u[:age]] }
#=> [{:name=>"Alice", :age=>20}, {:name=>"Alice", :age=>25}, {:name=>"Bob", :age=>30}]
# Кастомная логика сравнения
[5, 1, 3, 2, 4].sort { |a, b| a.odd? ? (b.odd? ? a <=> b : -1) : (b.odd? ? 1 : a <=> b) }
#=> [1, 3, 5, 2, 4] (сначала нечетные, затем четные)
Хэши в Ruby до версии 1.9 не сохраняли порядок элементов, но в современных версиях порядок сохраняется.
hash = {b: 2, a: 1, c: 3}
# Преобразование в массив и сортировка
hash.sort_by { |k, v| k } #=> [[:a, 1], [:b, 2], [:c, 3]]
# С сохранением в новый хэш (Ruby 3+)
hash.sort_by { |k, v| k }.to_h #=> {:a=>1, :b=>2, :c=>3}
hash = {a: 2, b: 1, c: 3}
# Сортировка по значению
hash.sort_by { |k, v| v } #=> [[:b, 1], [:a, 2], [:c, 3]]
people = {
'Alice' => {age: 25, score: 85},
'Bob' => {age: 30, score: 90},
'Charlie' => {age: 25, score: 95}
}
# Сортировка по возрасту, затем по score
people.sort_by { |name, data| [data[:age], -data[:score]] }
#=> [["Alice", {:age=>25, :score=>85}], ["Charlie", {:age=>25, :score=>95}], ["Bob", {:age=>30, :score=>90}]]
sort_by
обычно быстрее sort
с блоком, так как вычисляет ключ сортировки один раз для каждого элементаsort_by
parallel
для многопоточной сортировки# Сортировка строк с учетом локали
['é', 'a', 'ü', 'b'].sort_by { |s| s.downcase.unicode_normalize(:nfkd).gsub(/\p{Mn}/, '') }
#=> ["a", "b", "é", "ü"]
# Ленивая сортировка (Ruby 3.0+)
large_array.lazy.sort_by { |x| x.some_expensive_calculation }.first(10)
Резюмируем: Ruby предоставляет разнообразные методы сортировки как для массивов, так и для хэшей. Выбор конкретного метода зависит от требований к производительности, необходимости сохранения исходной коллекции и сложности критериев сортировки. Для большинства случаев sort_by
является оптимальным выбором благодаря балансу читаемости и производительности.