This is a straight forward solution using sort. The reverse order is created by negating the result of <=>:
sorted = some_things.sort do |x,y|
if x.a == y.a
x.b <=> y.b
else
-(x.a <=> y.a) # negate to reverse the order
end
end
Here's the complete program that tests it:
class Thing
attr_reader :a, :b
def initialize(a, b)
@a = a
@b = b
end
end
# Create some Things
some_things = [Thing.new("alpha","zebra"), Thing.new("gamma", "yoda"),
Thing.new("delta", "x-ray"), Thing.new("alpha", "yoda"),
Thing.new("delta", "yoda"), Thing.new("gamma", "zebra")]
sorted = some_things.sort do |x,y|
if x.a == y.a
x.b <=> y.b
else
-(x.a <=> y.a) # negate to reverse the order
end
end
p sorted
Which produces this output (newlines inserted):
[#<Thing:0x007fddca0949d0 @a="gamma", @b="yoda">,
#<Thing:0x007fddca0947f0 @a="gamma", @b="zebra">,
#<Thing:0x007fddca094958 @a="delta", @b="x-ray">,
#<Thing:0x007fddca094868 @a="delta", @b="yoda">,
#<Thing:0x007fddca0948e0 @a="alpha", @b="yoda">,
#<Thing:0x007fddca094a48 @a="alpha", @b="zebra">]