<- Printing the addressbook
Writing good programs ->

Sorting the addressbook

We chose to represent the addressbook as an array because arrays have an associated order. Say that we want to change that order. Suppose, for instance, that we want to sort the array alphabecially. How do we do that?

A second look at Array#sort

We have already used Array#sort to sort strings and integers. But how can we sort a more complex structure?

When the default behaviour is not what you want, Array#sort allows you to tell it how to sort the data structure. Let's start with an example simpler than the addressbook:


friends = [
    [ "Joe", "Smith" ],
    [ "Melissa", "Adams"],  
    [ "Sandy", "Koh" ]
]
                       

We know that, by defalt, Array#sort will sort by the first entry - in this case, first names. But say that we want to sort by last names instead. Array#sort is not an iterator, but just like iterators it allows you to give it a block of code. Like so:


friends.sort do |a,b|  
    ...
end
                       

What this code should do is:

With this information, the sort function knows how to sort your array.

Return values

How do you "return" a value? The return value is simply the value of the last statement executed. Let's take another look at irb


>> num = 3
=> 3
>> 2 + 3
=> 5
                       

That => 3 and that => 5 are the return values of those expressions.

The <=> operator.

Sorting is so common, that there is an operator to simplyfy return values. The operator <=> returns the -1, 0, or 1 that you would normally have received. Try it in irb


>> 3 <=> 1  # 3 > 1 so <=> returns 1
=> 1
>> 3 <=> 3  # 3 == 3 so <=> returns 0
=> 0
>> 3 <=> 5  # 3 < 5 so <=> returns -1
=> -1
>> "andy" <=> "sam" # "andy" comes before "sam"  
=> -1
                       

Sorting by last name

So we have:


friends.sort do |a,b|  
    ...
end
                       

a and b are elements of the array friends. The usual "friends.sort" is equivalent to:


friends.sort do |a,b|  
    a[0] <=> b[0]   # Sort by first entry  
end
                       

But we want to sort by the second entry (last name). So, instead we do:


friends = friends.sort do |a,b|  
    a[1] <=> b[1]   # Sort by second entry  
end
# Now 'friends' is sorted by last name.
                       

Sorting the addressbook

Now that we understand Array#sort better, we are ready to use a customized sort of the addressbook. We have:


addressbook.sort do |person_a, person_b|  
    ...
end
                       

person_a and person_b are both person structures. We can, for instance, sort them alphabetically by first name.


# p_a == "person a"
addressbook.sort do |p_a, p_b|
    p_a["first name"] <=> p_b["first name"]  
end
                       

Exercises

<- Printing the addressbook
Writing good programs ->