Sorting arrays and hashes in Ruby

Sorting an array

Using .sort and .sort!

Ruby has two handy methods that can be used for sorting arrays .sort and .sort! method. By default comparisons between elements are implemented using <=> operator, or using an optional code block that can be passed to these methods. The important difference between .sort and .sort! is that the first one returns a copy of an original array, while the second one modifies the original data.

The three-way comparison operator <=> that is sometimes called ?the spaceship operator? works by returning 1 (if greater than), 0 (if equal), or -1 (if less than).

Let?s see some examples:

[1, 25, 5, 15, 10, 20].sort=> [1, 5, 10, 15, 20, 25] #Note that unlike in using Javascript’s .sort() method, Ruby’s .sort works for sorting multiple digit numbers.arr = [‘Banana’, ‘Apple’, ‘Mango’, ‘Passionfruit’, ‘Pineapple’]arr.sort=> [“Apple”, “Banana”, “Mango”, “Passionfruit”, “Pineapple”]

In case of a custom sort such as reverse sorting, for instance, we would pass a block to .sort method and use that spaceship <=> operator I mentioned before:

arr = [‘Banana’, ‘Apple’, ‘Mango’, ‘Passionfruit’, ‘Pineapple’]arr.sort { |a,b| b <=> a}=> [“Pineapple”, “Passionfruit”, “Mango”, “Banana”, “Apple”]

Using .sort_by

Ruby?s .sort_by enumerable method sorts data using a set of keys generated by mapping the values of the array through the given block.

arr = [‘Banana’, ‘Apple’, ‘Mango’, ‘Passionfruit’, ‘Pineapple’]arr.sort_by{ |word| word.length }=> [“Apple”, “Mango”, “Banana”, “Pineapple”, “Passionfruit”]

Same operation can be performed using Ruby?s syntactic sugar for enumerables:

arr.sort_by(&:length)=> [“Apple”, “Mango”, “Banana”, “Pineapple”, “Passionfruit”]

This cool trick of putting ?-? in front of the sorting function can be used to reverse sort using sort_by:

arr.sort_by { |word| -word.length } => [“Passionfruit”, “Pineapple”, “Banana”, “Apple”, “Mango”]

Let?s see other capabilities of passing a custom block to .sort_by method. For instance, we can use a regular expression to identify numbers in the string and sort by numbers accordingly:

arr = [“10 Apples”, “5 Mangos”, “25 Bananas”, “15 Pineapples”, “20 Passionfruits”]arr.sort_by { |s| s.scan(/d+/).first.to_i }I used a regular expression (d+) to match the numbers, then get the first number (first) & convert it to an integer object (to_i).

In this case regular expression /d+/ matches one or more numbers. By definition .scan method returns an array of matches, so we grab the first value, convert it to integer and then finally perform our sorting by that integer value.

I covered some of the most commonly used applications of Ruby?s sorting methods for arrays. Stay tuned for part 2, where I?ll talk about sorting hashes!

23