On Tue, 15 Aug 2006 07:02:52 +0900, Gennady Bystritsky wrote:

>> Hi,
>> 
>> Here my - strange - problem.
>> 
>> To explain it, let's take the example of football. I 
>> construct an array 
>> of hashes of the results with team_id, total of pts, number of wins, 
>> number of draws and number of defeats such as:
>> 
>> myArray = Array.new
>> myArray << {:team_id=>1, :pts=>5, :w=>0,  :d=>5, :l=>5}
>> myArray << {:team_id=>2, :pts=>7, :w=>1,  :d=>4, :l=>5}
>> myArray << {:team_id=>3, :pts=>4, :w=>0,  :d=>4, :l=>6}
>> myArray << {:team_id=>4, :pts=>6, :w=>1,  :d=>3, :l=>6}
>> myArray << {:team_id=>5, :pts=>5, :w=>0,  :d=>5, :l=>5}
>> myArray << {:team_id=>6, :pts=>5, :w=>0,  :d=>5, :l=>5}
>> myArray << {:team_id=>8, :pts=>10, :w=>2,  :d=>4, :l=>4}
>> myArray << {:team_id=>9, :pts=>5, :w=>1,  :d=>2, :l=>7}
>> myArray << {:team_id=>10, :pts=>8, :w=>1,  :d=>5, :l=>4}
>> myArray << {:team_id=>11, :pts=>9, :w=>2,  :d=>3, :l=>5}
>> myArray << {:team_id=>12, :pts=>6, :w=>1,  :d=>3, :l=>6}
>> myArray << {:team_id=>13, :pts=>5, :w=>0,  :d=>5, :l=>5}
>> 
>> Now, from this array, I want to get the table.
>> So what I want to do is to sort the array,  first by total of 
>> pts, then 
>> by number of wins (if 2 teams have the same total of points I 
>> put first 
>> the team with more wins) and then by number of draws.
>> 
>> That's how - logically - I would do it anyway. But that does 
>> not seem to 
>> be the Ruby way. Doing it that way gives me a complete mess.
>> 
>> No worries, doing it the other way round works (first sort by 
>> draw, then 
>> wins, then pts)! Here is what I run:
>> 
>> puts "Team, Pts, W, D, L"
>> myArray = myArray.sort { |a,b| b[:d] <=> a[:d]
>> 		}.sort { |a,b| b[:w] <=> a[:w]
>> 		}.sort { |a,b| b[:pts] <=> a[:pts]
>> 		}.each do |row|
>> puts "#{row[:team_id]}, #{row[:pts]}, #{row[:w]}, #{row[:d]}, 
>> #{row[:l]}"
>> end
>> 
>> Did I say it works? Well almost! Here is my output:
>> 
>> Team, Pts, W, D, L
>> 8, 10, 2, 4, 4
>> 11, 9, 2, 3, 5
>> 10, 8, 1, 5, 4
>> 2, 7, 1, 4, 5
>> 4, 6, 1, 3, 6
>> 12, 6, 1, 3, 6
>> 16, 5, 0, 5, 5
>> 1, 5, 0, 5, 5
>> 9, 5, 1, 2, 7
>> 5, 5, 0, 5, 5
>> 6, 5, 0, 5, 5
>> 3, 4, 0, 4, 6
>> 
>> Good news, we kept the correct team_is with the correct result.
>> But can anyone explain me what on earth is the line 9, 5, 1, 
>> 2, 7 doing 
>> there in the middle?
>> 
>> Thanks for your help!
> 
> Each of your sort's just re-arranges the array by the new criteria,
> completely unrelated to previous sorts. Why not simply to create an
> appropriate criteria for a single sort:

Not of .sort is a stable sort. Then it will preserve the order of items
that are equal according to the current comparison. You would sort from
least significant to most significant exactly as he has done here.

From the results though, I conclude that .sort isn't a stable sort.

Looking through the C code, I see that .sort is a quicksort.

http://en.wikipedia.org/wiki/Sorting_algorithm#List_of_sorting_algorithms

--Ken

-- 
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/