From: Rick DeNatale Date: 2007-03-28T01:10:13+09:00 Subject: Re: sorting an array based on two attributes of objects On 3/26/07, Alex Young wrote: > senthil wrote: > > Thanks for some of your replies for the lst post i need small > > modification in that post .. i want to sort the salary in descending > > order. i have explained the same quesion again.... > > > > Hi all, > > I want to sort the objects of array based on two attributes.I want > > sort an employee class based on his salary in descecding order and name > > , so that if two > > person has same salary it should be sorted with name. > > Lets say for example the employee objects has following name and > > salary. > > > > name salary > > d 100 > > c 200 > > b 50 > > a 100 > > > > > > so in this case the result which i expect is > > > > name salary > > b 200 > > a 100 > > d 100 > > c 50 > > > > Note:In the above example for salary 100 the sorting is done > > alphabetically, but initially(before sorting) 'd' came first and then > > 'a' came.so basically i want to sort the array with more than one order. > > Can any one help me to solve it ?? > > > In this case, just invert the salary: > > sorted_employees = employees.sort_by { |e| [ -e.salary, e.name ] } > > I can't think of a way offhand to have different lexicographic orderings > in the same sort, though. Someone, in another recent thread, came up with the idea of a reverse proxy class something like this class Reverse :attr_reader :obj def initialize(obj) @obj = obj end def <=>(other) other.obj <=> self.obj end end so let's say you wanted to sort the names in descending order as well: sorted_employees = employees.sort_by { |e| [-e.salary, Reverse.new(e.name) ] } You could even use this "reverse" proxy to change the sorting of salary, so that the original could be: sorted_employees = employees.sort_by { |e| [ Reverse.new(e.salary), e.name ] } One could quibble about the name Reverse. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/