From: Rob Biedenharn Date: 2010-03-26T02:42:39+09:00 Subject: Re: problem sorting Since no one has duplicated what you seemed to be trying: On Mar 25, 2010, at 11:31 AM, Jesús Gabriel y Galán wrote: > On Thu, Mar 25, 2010 at 3:58 PM, Augusto Garcia > wrote: >> I am trying to sort an array using a block but somehow I am not >> seeing >> what I am want. First I want to sort the total, then break the tie on >> gold goldcount, silvercount and finally on bronzcount >> >> Here is my code. what am I missing? please help >> >> # compare and order by totals >> result = b[:total] <=> a[:total] >> # if tied, break the number of gold medals >> result != 0 ? result : b[:goldcount] <=> a[:goldcount] >> result != 0 ? result : b[:silvercount] <=> a[:silvercount] >> result != 0 ? result : b[:bronzcount] <=> a[:bronzcount] >> result != 0 ? result : b[:country] <=> a[:country] >> end > .sort {|a,b| (b[:total] <=> a[:total]).nonzero? || (b[:goldcount] <=> a[:goldcount]).nonzero? || (b[:silvercount] <=> a[:silvercount]).nonzero? || (b[:bronzcount] <=> a[:bronzcount]).nonzero? || b[:country] <=> a[:country] } Look at what Numeric#nonzero? is meant for ;-) Also, your original breaks the final tie by reverse sort of the country so I do here as well. Augusto has an ascending sort on all and Jesús just has an ascending sort on the country. -Rob > I assume you have an array of hashes: > > irb(main):001:0> country_medals = [] > => [] > > irb(main):002:0> country_medals << {:country => "Spain", :total => > 100, :goldcount => 100, :silvercount => 0, :bronzecount => 0} > => [{:country=>"Spain", :total=>100, :goldcount=>100, :silvercount=>0, > :bronzecount=>0}] > > irb(main):003:0> country_medals << {:country => "US", :total => 50, > :goldcount => 50, :silvercount => 0, :bronzecount => 0} > => [{:country=>"Spain", :total=>100, :goldcount=>100, :silvercount=>0, > :bronzecount=>0}, {:country=>"US", :total=>50, :goldcount=>50, > :silvercount=>0, :bronzecount=>0}] > > irb(main):004:0> country_medals << {:country => "UK", :total => 50, > :goldcount => 45, :silvercount => 5, :bronzecount => 0} > => [{:country=>"Spain", :total=>100, :goldcount=>100, :silvercount=>0, > :bronzecount=>0}, {:country=>"US", :total=>50, :goldcount=>50, > :silvercount=>0, :bronzecount=>0}, {:country=>"UK", :total=>50, > :goldcount=>45, :silvercount=>5, :bronzecount=>0}] > > irb(main):010:0> country_medals.sort_by {|x| [-x[:total], > -x[:goldcount], -x[:silvercount], -x[:bronzecount], x[:country]]} > => [{:country=>"Spain", :total=>100, :goldcount=>100, :silvercount=>0, > :bronzecount=>0}, {:country=>"US", :total=>50, :goldcount=>50, > :silvercount=>0, :bronzecount=>0}, {:country=>"UK", :total=>50, > :goldcount=>45, :silvercount=>5, :bronzecount=>0}] > > > Jesus. > Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com