Hello, and welcome back! Our journey today takes us into the sorting universe in Ruby. We will learn and utilize Ruby's powerful sorting methods: sort
and sort_by
. These tools in Ruby significantly simplify the task of sorting. Let's get started!
Sorting refers to arranging data in a specific order, which enhances the efficiency of search or merge operations on data. In real life, we sort books alphabetically or clothes by size. Similar concepts are applicable in programming, where sorting large lists of data for more effective analysis is a frequent practice.
Ruby offers built-in sorting methods: sort
for arrays and other enumerables, and sort_by
for more complex sorting logic. Here's a demonstration of how we use these methods:
Sorting with sort
makes sorting arrays of primitives a breeze. Let's see it in action!
Sorting Arrays of Primitives
Ruby1arr = [4, 1, 3, 2] 2sorted_arr = arr.sort 3puts sorted_arr.join(", ") # Output: 1, 2, 3, 4
Sorting Lists of Objects
Ruby1inventory = ["Bananas", "Pears", "Apples", "Dates"] 2sorted_inventory = inventory.sort 3sorted_inventory.each do |item| 4 puts item 5end 6 7# Output: 8# Apples 9# Bananas 10# Dates 11# Pears
As you can see, sorting in Ruby is as simple as that!
Ruby allows us to define custom sorting logic using blocks. Let's sort a list of students by their grades, with alphabetical sorting applied in the event of ties in grades. First, let's define the Student
class:
Ruby1class Student 2 attr_reader :name, :grade 3 4 def initialize(name, grade) 5 @name = name 6 @grade = grade 7 end 8 9 def to_s 10 "#{name}:#{grade}" 11 end 12end
Here's how we perform custom sorting using Ruby's block syntax:
Ruby1students = [ 2 Student.new("Alice", 85), 3 Student.new("Bob", 90), 4 Student.new("Charlie", 90) 5] 6 7sorted_students = students.sort do |s1, s2| 8 grade_comparison = s2.grade <=> s1.grade 9 grade_comparison == 0 ? s1.name <=> s2.name : grade_comparison 10end 11 12puts sorted_students.join(", ") # Output: Bob:90, Charlie:90, Alice:85
In the example above, we create an array of Student
objects and sort it using a custom comparison defined via a block. The block first compares Student
objects based on their grades in descending order and, in the event of a tie, compares their names in alphabetical order. The <=>
operator returns an integer that indicates the relative order of the objects being compared.
To sort students by grades in ascending order but names in descending order in case of ties, you can adjust the block by flipping the order of the comparisons:
Ruby1sorted_students = students.sort do |s1, s2| 2 grade_comparison = s1.grade <=> s2.grade 3 grade_comparison == 0 ? s2.name <=> s1.name : grade_comparison 4end 5 6puts sorted_students.join(", ") # Output: Alice:85, Charlie:90, Bob:90
Here, the custom comparison sorts the grades in ascending order while sorting names in descending order when the grades are the same.
While sort
with a block can use custom sorting logic, sort_by
can optimize performance particularly on large datasets by computing the sorting criterion once per element. Here's an example of sorting students first by grade and then name using sort_by
:
Ruby1sorted_students = students.sort_by { |student| [student.grade, student.name] } 2puts sorted_students.join(", ") # Output: Alice:85, Bob:90, Charlie:90
sort_by
first evaluates the block for each element in the array, which results in an array of key-object pairs. The array is then sorted, and finally, the original collection is reordered based on this. This can provide a performance boost because it replaces multiple evaluations of a sorting criterion with a single evaluation.
Well done! You've learned how Ruby's sorting functions work and you have utilized Ruby's powerful sorting methods.
In our future lessons, we'll delve deeper into sorting and tackle more intricate problems. So, stay tuned and get ready to sort your way to success! Happy coding!
