sorting an array based on two attributes of objects

S

senthil

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 ??
 
A

Alex Young

senthil said:
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.
 
I

Ilan Berci

senthil said:
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....

I came up with this which is sub par as I test for a condition twice so
stay tuned for a better solution..

irb(main):001:0> [['d',100],['c',200],['b',50],['a',100]].sort {|a,b|
b[1]==a[1]?a[0]<=>b[0]:b[1]<=>a[1]}
=> [["c", 200], ["a", 100], ["d", 100], ["b", 50]]

hope this helps

ilan
 
I

Ilan Berci

Alex said:
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.

Doh!!!! Ofcourse! Ok.. more coffee for me..

<sulks away with his tail between his legs>

ilan
 
R

Rob Biedenharn

senthil said:
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....

I came up with this which is sub par as I test for a condition
twice so
stay tuned for a better solution..

irb(main):001:0> [['d',100],['c',200],['b',50],['a',100]].sort {|a,b|
b[1]==a[1]?a[0]<=>b[0]:b[1]<=>a[1]}
=> [["c", 200], ["a", 100], ["d", 100], ["b", 50]]

hope this helps

ilan

Just to add a bit to this: consider using .nonzero? for chained
comparisons

[['d',100],['c',200],['b',50],['a',100]].
sort {|a,b| (b[1]<=>a[1]).nonzero? || a[0]<=>b[0] }

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
R

Rick DeNatale

senthil said:
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 :eek:bj

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.
 
A

Alex Young

Rick said:
On 3/26/07, Alex Young <[email protected]> wrote:
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 :eek:bj

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 ] }

That's lovely. My brain wandered off down the String#invert route, and
I ended up getting tied in knots over multibyte encodings. Reverse is a
*much* nicer trick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top