I'm trying to sort an array of objects based upon different attributes. Some of those attributes I would like to sort in ascending order and some in descending order. I have been able to sort by ascending or descending but have been unable to combine the two.

Here is the simple class I am working with:

class Dog
  attr_reader :name, :gender

  DOGS = []

  def initialize(name, gender)
    @name = name
    @gender = gender
    DOGS << self
  end

  def self.all
    DOGS
  end

  def self.sort_all_by_gender_then_name
    self.all.sort_by { |d| [d.gender, d.name] }
  end
end

I can then instantiate some dogs to be sorted later.

@rover = Dog.new("Rover", "Male")
@max = Dog.new("Max", "Male")
@fluffy = Dog.new("Fluffy", "Female")
@cocoa = Dog.new("Cocoa", "Female")

I can then use the sort_all_by_gender_then_name method.

Dog.sort_all_by_gender_then_name
=> [@cocoa, @fluffy, @max, @rover]

The array it returns includes females first, then males, all sorted by name in ascending order.

But what if I want to have gender be descending, and then name ascending, so that it would be males first and then sorted by name ascending. In this case:

=> [@max, @rover, @cocoa, @fluffy]

Or, if I wanted it by gender ascending, but name descending:

=> [@fluffy, @cocoa, @rover, @max]

When sorting numerical values, you can prepend a - to make it sort in reverse. However, I have been unable to find a way to do this with strings. Any help or ideas would be appreciated. Thanks.

Edit
Report