Velocity Reviews > Ruby > problem sorting

# problem sorting

Augusto Garcia
Guest
Posts: n/a

 03-25-2010
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

# 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
--
Posted via http://www.ruby-forum.com/.

Jesús Gabriel y Galán
Guest
Posts: n/a

 03-25-2010
On Thu, Mar 25, 2010 at 3:58 PM, Augusto Garcia <(E-Mail Removed)> 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
>
>
> =A0# compare and order by totals
> =A0 =A0 =A0 =A0result =3D b[:total] <=3D> a[:total]
> =A0 =A0 =A0 =A0# if tied, break the number of gold medals
> =A0 =A0 =A0 =A0result !=3D 0 ? result : b[:goldcount] <=3D> a[:goldcount]
> =A0 =A0 =A0 =A0result !=3D 0 ? result : b[:silvercount] <=3D> a[:silverco=

unt]
> =A0 =A0 =A0 =A0result !=3D 0 ? result : b[:bronzcount] <=3D> a[:bronzcoun=

t]
> =A0 =A0 =A0 =A0result !=3D 0 ? result : b[:country] <=3D> a[:country]
> =A0end

I assume you have an array of hashes:

irb(main):001:0> country_medals =3D []
=3D> []

irb(main):002:0> country_medals << {:country =3D> "Spain", :total =3D>
100, :goldcount =3D> 100, :silvercount =3D> 0, :bronzecount =3D> 0}
=3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, :silvercount=
=3D>0,
:bronzecount=3D>0}]

irb(main):003:0> country_medals << {:country =3D> "US", :total =3D> 50,
:goldcount =3D> 50, :silvercount =3D> 0, :bronzecount =3D> 0}
=3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, :silvercount=
=3D>0,
:bronzecount=3D>0}, {:country=3D>"US", :total=3D>50, :goldcount=3D>50,
:silvercount=3D>0, :bronzecount=3D>0}]

irb(main):004:0> country_medals << {:country =3D> "UK", :total =3D> 50,
:goldcount =3D> 45, :silvercount =3D> 5, :bronzecount =3D> 0}
=3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, :silvercount=
=3D>0,
:bronzecount=3D>0}, {:country=3D>"US", :total=3D>50, :goldcount=3D>50,
:silvercount=3D>0, :bronzecount=3D>0}, {:country=3D>"UK", :total=3D>50,
:goldcount=3D>45, :silvercount=3D>5, :bronzecount=3D>0}]

irb(main):010:0> country_medals.sort_by {|x| [-x[:total],
-x[:goldcount], -x[:silvercount], -x[:bronzecount], x[:country]]}
=3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, :silvercount=
=3D>0,
:bronzecount=3D>0}, {:country=3D>"US", :total=3D>50, :goldcount=3D>50,
:silvercount=3D>0, :bronzecount=3D>0}, {:country=3D>"UK", :total=3D>50,
:goldcount=3D>45, :silvercount=3D>5, :bronzecount=3D>0}]

Jesus.

Rob Biedenharn
Guest
Posts: n/a

 03-25-2010
Since no one has duplicated what you seemed to be trying:

On Mar 25, 2010, at 11:31 AM, Jes=FAs Gabriel y Gal=E1n wrote:
> On Thu, Mar 25, 2010 at 3:58 PM, Augusto Garcia <(E-Mail Removed)> =20
> wrote:
>> I am trying to sort an array using a block but somehow I am not =20
>> seeing
>> what I am want. First I want to sort the total, then break the tie on
>> gold goldcount, silvercount and finally on bronzcount
>>
>>
>> # compare and order by totals
>> result =3D b[:total] <=3D> a[:total]
>> # if tied, break the number of gold medals
>> result !=3D 0 ? result : b[:goldcount] <=3D> a[:goldcount]
>> result !=3D 0 ? result : b[:silvercount] <=3D> a[:silvercount]
>> result !=3D 0 ? result : b[:bronzcount] <=3D> a[:bronzcount]
>> result !=3D 0 ? result : b[:country] <=3D> a[:country]
>> end

>

.sort {|a,b|
(b[:total] <=3D> a[:total]).nonzero? ||
(b[:goldcount] <=3D> a[:goldcount]).nonzero? ||
(b[:silvercount] <=3D> a[:silvercount]).nonzero? ||
(b[:bronzcount] <=3D> a[:bronzcount]).nonzero? ||
b[:country] <=3D> a[:country]
}

Look at what Numeric#nonzero? is meant for

Also, your original breaks the final tie by reverse sort of the =20
country so I do here as well. Augusto has an ascending sort on all and =20=

Jes=FAs just has an ascending sort on the country.

-Rob

> I assume you have an array of hashes:
>
> irb(main):001:0> country_medals =3D []
> =3D> []
>
> irb(main):002:0> country_medals << {:country =3D> "Spain", :total =3D>
> 100, :goldcount =3D> 100, :silvercount =3D> 0, :bronzecount =3D> 0}
> =3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, =

:silvercount=3D>0,
> :bronzecount=3D>0}]
>
> irb(main):003:0> country_medals << {:country =3D> "US", :total =3D> =

50,
> :goldcount =3D> 50, :silvercount =3D> 0, :bronzecount =3D> 0}
> =3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, =

:silvercount=3D>0,
> :bronzecount=3D>0}, {:country=3D>"US", :total=3D>50, :goldcount=3D>50,
> :silvercount=3D>0, :bronzecount=3D>0}]
>
> irb(main):004:0> country_medals << {:country =3D> "UK", :total =3D> =

50,
> :goldcount =3D> 45, :silvercount =3D> 5, :bronzecount =3D> 0}
> =3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, =

:silvercount=3D>0,
> :bronzecount=3D>0}, {:country=3D>"US", :total=3D>50, :goldcount=3D>50,
> :silvercount=3D>0, :bronzecount=3D>0}, {:country=3D>"UK", :total=3D>50,
> :goldcount=3D>45, :silvercount=3D>5, :bronzecount=3D>0}]
>
> irb(main):010:0> country_medals.sort_by {|x| [-x[:total],
> -x[:goldcount], -x[:silvercount], -x[:bronzecount], x[:country]]}
> =3D> [{:country=3D>"Spain", :total=3D>100, :goldcount=3D>100, =

:silvercount=3D>0,
> :bronzecount=3D>0}, {:country=3D>"US", :total=3D>50, :goldcount=3D>50,
> :silvercount=3D>0, :bronzecount=3D>0}, {:country=3D>"UK", :total=3D>50,
> :goldcount=3D>45, :silvercount=3D>5, :bronzecount=3D>0}]
>
>
> Jesus.
>

Rob Biedenharn http://agileconsultingllc.com
http://www.velocityreviews.com/forums/(E-Mail Removed)