Quick answer
In Ruby, the primary way to sort an array is sort for basic ordering and sort_by for efficient, multi-key ordering. Use sort.reverse or sort { |a,b| b <=> a } for descending results, and prefer sort_by when performance matters. The default sort is stable in Ruby 2.4+.
Why sorting matters in Ruby programs
Sorting arrays is a common operation that affects readability, correctness, and performance. Choosing the right method and options helps you produce predictable results and avoid subtle bugs when ordering strings, numbers, or complex objects. This guide focuses on core techniques, edge cases, and performance tradeoffs you can rely on.
Basic sorting with sort
sort uses the elements’ <=> operator and returns a new sorted array, leaving the original unchanged. It works for numbers, strings, and mixed-type arrays that define comparison. For descending order, chain reverse or provide a custom block.
Numeric examples
[3, 1, 2].sort#=> [1, 2, 3][3, 1, 2].sort.reverse#=> [3, 2, 1][3, 1, 2].sort { |a,b| b <=> a }#=> [3, 2, 1]
String examples
["pear", "apple", "banana"].sort#=> ["apple", "banana", "pear"]["pear", "apple", "banana"].sort.reverse#=> ["pear", "banana", "apple"]
Efficient sorting with sort_by
sort_by is often faster and more concise when sorting by one or more computed keys. It decorates each element with the key, sorts, then removes the decoration (Schwartzian transform). Use a tuple array for secondary sorting.
Sorting by a single key
users.sort_by { |u| u[:age] }
Sorting by multiple keys
items.sort_by { |i| [i[:category], i[:name]] }
Case-insensitive and locale-sensitive sorting
Use upcase or downcase with sort_by for case-insensitive results. For locale-aware ordering in Rails, use Ruby.on Rails’s casecmp or ActiveSupport’s transliterate when needed.
names.sort_by { |n| n.downcase }
Custom comparators and sort! mutation
For fine-grained control, pass a block to sort or sort_by. Use sort! to sort in place, and sort_by! when available. Be cautious with complex multi-key logic; prefer sort_by with tuples for stability and clarity.
Stability and performance notes
Ruby’s sort has been stable since Ruby 2.4, meaning equal elements retain their input order. For most use cases, sort_by is faster and less error-prone. Reserve custom blocks for edge cases where sort_by semantics are insufficient.
| Method | Use case | Returns | Performance note |
|---|---|---|---|
| sort | Simple comparisons | New array | General-purpose, stable since 2.4 |
| sort! | In-place sort | Receiver | Memory efficient; mutates input |
| sort_by | Expensive or multiple keys | New array | Often faster with many elements |
| sort_by! | In-place key-based sort | Receiver | Available; mutates input |