How do I alphabetize an array ignoring case?
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
user2608684
Updated on July 09, 2022Comments
-
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 almost 11 yearsHere'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 over 10 yearsFor 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 about 9 yearsI'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.