What's the ruby way to sort string with cases in mind

Discussion in 'Ruby' started by Sam Kong, Sep 19, 2006.

  1. Sam Kong

    Sam Kong Guest

    Hi,

    I'd like to sort an array of strings case-insensitively.
    However, if 2 strings are case-insensitively same, I want capital
    letters to come first.

    a = %w(a c b A C B)
    a.sort_by { |i| i.upcase } # => ["a", "A", "b", "B", "c", "C"]

    Actually, I want ["A", "a", "B", "b", "C", "c"] .
    I can get the result with the following trick.

    a.sort_by {|i| i.upcase + i}

    But I think there's a more rubyish way.
    How do you do that?

    Thanks in advance.

    Sam
    Sam Kong, Sep 19, 2006
    #1
    1. Advertising

  2. Sam Kong wrote:
    > I'd like to sort an array of strings case-insensitively.

    Alternate method (slightly "faster", maybe):
    a = %w(a c b A C B)
    a.sort {|a,b| a.casecmp b} #=> ["a", "A", "b", "B", "c", "C"]

    > Actually, I want ["A", "a", "B", "b", "C", "c"] .
    > I can get the result with the following trick.
    >
    > a.sort_by {|i| i.upcase + i}

    Clever.

    > But I think there's a more rubyish way.
    > How do you do that?

    No clue. Maybe implement your own comparator? {|a,b| dict_order(a,b)}?

    Devin
    Devin Mullins, Sep 20, 2006
    #2
    1. Advertising

  3. Sam Kong

    MonkeeSage Guest

    Sam Kong wrote:
    > But I think there's a more rubyish way.
    > How do you do that?


    Hi Sam,

    I think that's probably the most concise and rubyish way. You can't do
    a (simple) sort by ascii ordinal (i[0] in 1.8, or i.ord in 1.9), as
    that would give you all the capitals first. And implementing your own
    sort routine is not going to be anywhere near as clean as what you've
    got. So yeah, imo, go with what you have, it's nice. :)

    Regards,
    Jordan
    MonkeeSage, Sep 20, 2006
    #3
  4. > And implementing your own
    > sort routine is not going to be anywhere near as clean as what you've
    > got.


    My best try so far is like that:

    a.sort{ |i,j| (i.upcase == j.upcase)? (i<=>j):(i.upcase<=>j.upcase) }

    Not elegant, but not too ugly (or is it?). I've got a feeling there
    must be a way to simplify this.


    Regards,
    Rimantas
    --
    http://rimantas.com/
    Rimantas Liubertas, Sep 20, 2006
    #4
  5. On 20.09.2006 09:19, Rimantas Liubertas wrote:
    >> And implementing your own
    >> sort routine is not going to be anywhere near as clean as what you've
    >> got.

    >
    > My best try so far is like that:
    >
    > a.sort{ |i,j| (i.upcase == j.upcase)? (i<=>j):(i.upcase<=>j.upcase) }
    >
    > Not elegant, but not too ugly (or is it?). I've got a feeling there
    > must be a way to simplify this.


    a.sort {|i,j| i.upcase == j.upcase ? i <=> j : i.upcase <=> j.upcase}
    :)

    Maybe a bit more efficient:

    a.sort do |i,j|
    cmp = i.downcase <=> j.downcase
    cmp == 0 ? i <=> j : cmp
    end

    Cheers

    robert
    Robert Klemme, Sep 20, 2006
    #5
  6. Sam Kong

    MonkeeSage Guest

    I shouldn't have underestimated my fellow rubyists. I guess
    implementing your own sort routine _can_ be *near* as clean. ;)

    Regards,
    Jordan
    MonkeeSage, Sep 20, 2006
    #6
  7. Hi,

    "Rimantas Liubertas" <> writes:

    >
    > > And implementing your own
    > > sort routine is not going to be anywhere near as clean as what you've
    > > got.

    >
    > My best try so far is like that:
    >
    > a.sort{ |i,j| (i.upcase == j.upcase)? (i<=>j):(i.upcase<=>j.upcase) }
    >
    > Not elegant, but not too ugly (or is it?). I've got a feeling there
    > must be a way to simplify this.


    a.sort{ |i,j| [i.upcase, i] <=> [j.upcase, j] }

    a.sort_by{ |i| [i.upcase, i] }

    --
    eban
    WATANABE Hirofumi, Sep 20, 2006
    #7
  8. >
    > a.sort{ |i,j| [i.upcase, i] <=> [j.upcase, j] }
    >
    > a.sort_by{ |i| [i.upcase, i] }


    Great! I guess we have the winner :)


    Regards,
    Rimantas
    --
    http://rimantas.com/
    Rimantas Liubertas, Sep 20, 2006
    #8
  9. Sam Kong

    MonkeeSage Guest

    Nice one, Hirofumi-shi! :)

    Regards,
    Jordan
    MonkeeSage, Sep 20, 2006
    #9
  10. On 20.09.2006 10:56, Rimantas Liubertas wrote:
    >>
    >> a.sort{ |i,j| [i.upcase, i] <=> [j.upcase, j] }
    >>
    >> a.sort_by{ |i| [i.upcase, i] }

    >
    > Great! I guess we have the winner :)


    +1

    robert
    Robert Klemme, Sep 20, 2006
    #10
  11. Sam Kong

    Sam Kong Guest

    Hi,

    WATANABE Hirofumi wrote:
    > Hi,
    >
    > "Rimantas Liubertas" <> writes:


    > a.sort{ |i,j| [i.upcase, i] <=> [j.upcase, j] }
    >
    > a.sort_by{ |i| [i.upcase, i] }


    Wow!
    This is what I was looking for.
    Why couldn't I think of this?

    Thank you very much.

    Sam
    Sam Kong, Sep 20, 2006
    #11
    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. Raghuram Devarakonda

    Connecting multiple test cases in a sort of pipe

    Raghuram Devarakonda, Jul 30, 2009, in forum: Python
    Replies:
    2
    Views:
    294
    Raghuram Devarakonda
    Jul 30, 2009
  2. Navin
    Replies:
    1
    Views:
    688
    Ken Schaefer
    Sep 9, 2003
  3. Replies:
    11
    Views:
    194
    Uri Guttman
    Jun 26, 2007
  4. Terry Reedy

    Re: unittest - sort cases to be run

    Terry Reedy, Aug 21, 2012, in forum: Python
    Replies:
    2
    Views:
    173
    goon12
    Aug 21, 2012
  5. Peter Otten

    Re: unittest - sort cases to be run

    Peter Otten, Aug 21, 2012, in forum: Python
    Replies:
    0
    Views:
    151
    Peter Otten
    Aug 21, 2012
Loading...

Share This Page