How do I alphabetize an array ignoring case?

34,402

Solution 1

How about:

wordlist.sort_by { |word| word.downcase }

Or even shorter:

wordlist.sort_by(&:downcase)

Solution 2

In general, sort_by is not efficient for keys that are simple to compute. A more efficient comparison is to use sort with a block and replace the default comparison operator <=> with casecmp

wordlist.sort { |w1, w2| w1.casecmp(w2) }

For more information about efficiency gains, consult the official Ruby documentation for the sort_by method: http://www.ruby-doc.org/core-2.1.2/Enumerable.html#method-i-sort_by

Share:
34,402
user2608684
Author by

user2608684

Updated on July 09, 2022

Comments

  • user2608684
    user2608684 almost 2 years

    I'm using Chris Pine's Learn to Program and am stumped on his relatively simple challenge to take user input in the form of a list of random words and then alphabetize them in an array. Questions about this challenge have come up before, but I haven't been able to find my specific question on SO, so I'm sorry if it's a duplicate.

    puts "Here's a fun trick. Type as many words as you want (one per line) and 
    I'll sort them in...ALPHABETICAL ORDER! Hold on to your hats!"
    wordlist = Array.new
    while (userInput = gets.chomp) != ''
       wordlist.push(userInput)
    end
    puts wordlist.sort
    

    While this does the trick, I'm trying to figure out how to alphabetize the array without case-sensitivity. This is hard to wrap my head around. I learned about casecmp but that seems to be a method for comparing a specific string, as opposed to an array of strings.

    So far I've been trying things like:

    wordlist.to_s.downcase.to_a.sort!
    

    which, in addition to looking bad, doesn't work for multiple reasons, including that Ruby 2.0 doesn't allow strings to be converted to arrays.

  • 7stud
    7stud almost 11 years
    Here's a tip: your are trying to do something to an array. So google "ruby Array". The first hit will usually be Class: XXX (Ruby). Those are the ruby docs for the class you searched for. Click on the link, and start scanning the methods listed on the left. If you can't find a method that will do what you want, the next place to check is in the "Included Modules" section also on the left. Click on Enumerable, and look through the methods there as well. In Enumerable, you will find sort_by().
  • Luke Griffiths
    Luke Griffiths over 10 years
    For methods like map, sort_by, select, where you're running a block on each item, you there is some syntactic sugar if your block consists of just calling a method on each item. It looks like this: wordlist.sort_by(&:downcase)
  • Kelvin
    Kelvin about 9 years
    I'm afraid that casecmp isn't a trivial operation like in the ruby-doc example, which merely returned the object itself. Try it yourself: ruby -rbenchmark -e 'n=10; shuffled_words = File.readlines("/usr/share/dict/words").map(&:chomp).shuffle‌​; puts "wordcount: #{shuffled_words.size}"; Benchmark.bmbm {|x| x.report("sort_by/downcase"){ n.times{ shuffled_words.sort_by(&:downcase) } }; x.report("sort/casecmp") { n.times{ shuffled_words.sort{|a,b| a.casecmp(b) }}}}'. sort_by is 40% faster in this case.