Thursday, November 17, 2011

Ruby: Sorting an array with multiple fields

I was working on a project today and needed to make some changes to the way an array on objects was sorted before being displayed on the screen. The main reason I even bothered to post this is to heap a little more praise on Ruby for working the way I expected it to work.

Here was my object (not tied to a database, just created for convenience):
class Force
attr_accessor :id
attr_accessor :last_name
attr_accessor :first_name
attr_accessor :rank
attr_accessor :shift
attr_accessor :promoted_on
attr_accessor :phone
attr_accessor :totalcount
end
I needed to sort an array of these objects by rank ascending, shift ascending, then promoted_on (date) descending.

I sorted them by concatenating the fields together and making the right comparisons. This only works because the first two fields, rank and shift, cannot be empty. Otherwise, a simple concatenation would create undesired results.

Sorting all fields ascending looks like this:
@forces = @forces.sort {|x,y| x.shift + x.rank + x.promoted_on.to_s <=> y.shift + y.rank + y.promoted_on.to_s}
To sort the promoted_on field in descending order, reverse the x,y sides for that field:
@forces = @forces.sort {|x,y| x.shift + x.rank + y.promoted_on.to_s <=> y.shift + y.rank + x.promoted_on.to_s}
No need for a special sort coding block. Ruby FTW!