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. Advertisements

  2. 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"]
    No clue. Maybe implement your own comparator? {|a,b| dict_order(a,b)}?

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

  3. Sam Kong

    MonkeeSage Guest

    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
    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
     
    Rimantas Liubertas, Sep 20, 2006
    #4
  5. 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,

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

    a.sort_by{ |i| [i.upcase, i] }
     
    WATANABE Hirofumi, Sep 20, 2006
    #7
  8. Great! I guess we have the winner :)


    Regards,
    Rimantas
     
    Rimantas Liubertas, Sep 20, 2006
    #8
  9. Sam Kong

    MonkeeSage Guest

    Nice one, Hirofumi-shi! :)

    Regards,
    Jordan
     
    MonkeeSage, Sep 20, 2006
    #9
  10. +1

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

    Sam Kong Guest

    Hi,

    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. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.