problem sorting

Discussion in 'Ruby' started by Augusto Garcia, Mar 25, 2010.

  1. 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
    --
    Posted via http://www.ruby-forum.com/.
     
    Augusto Garcia, Mar 25, 2010
    #1
    1. Advertising

  2. 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
    >
    > =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.
     
    Jesús Gabriel y Galán, Mar 25, 2010
    #2
    1. Advertising

  3. 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 <> =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
    >>
    >> Here is my code. what am I missing? please help
    >>
    >> # 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
     
    Rob Biedenharn, Mar 25, 2010
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hajime Kusakabe

    DataGrid - sorting/paging problem

    Hajime Kusakabe, Jul 30, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    503
    Saravana
    Jul 31, 2003
  2. Replies:
    2
    Views:
    1,491
    James Kanze
    Jul 6, 2010
  3. Jason
    Replies:
    0
    Views:
    412
    Jason
    Oct 4, 2006
  4. Tom Kirchner

    sorting by multiple criterias (sub-sorting)

    Tom Kirchner, Oct 11, 2003, in forum: Perl Misc
    Replies:
    3
    Views:
    514
    Michael Budash
    Oct 11, 2003
  5. Íéêüëáïò Êïýñáò

    Sorting a set works, sorting a dictionary fails ?

    Íéêüëáïò Êïýñáò, Jun 10, 2013, in forum: Python
    Replies:
    12
    Views:
    171
    Ulrich Eckhardt
    Jun 10, 2013
Loading...

Share This Page