From: Martin DeMello Date: 2008-08-12T02:35:07+09:00 Subject: Re: Sort array by two attributes? (like sql "order by A, B") On Mon, Aug 11, 2008 at 8:48 AM, Erik Veenstra wrote: >> That's a neat trick, thanks! I actually like the first one better >> though as you can swap a & b around in each test to get (eg) sorted by >> name ascending and then a date field descending. > > Just use -x.b: > > a.sort_by{|x| [x.name, -x.date]} Doesn't always work. I keep this handy: class RevCmp attr_reader :this def initialize(obj) @this = obj end def <=>(other) other.this <=> @this end # not delegating anything else because this is explicitly a throwaway # object used only inside a sort_by block end and then you have a.sort_by {|x| [x.name, RevCmp.new(x.date)]} you could even use a top-level method so you can say a.sort_by {|x| [x.name, descending(x.date)]} where descending(x) returns RevCmp.new(x) You could even mix it into object to get a.sort_by {|x| [x.name, x.date._descending_]} where I use the underscores as a cosmetic way of making it stand out inside the sort block martin