如何对一个数组进行字母排序,忽略大小写?

54

我正在使用Chris Pine的《学习编程》一书,对他比较简单的挑战感到困惑,即以随机单词列表的形式接受用户输入,然后在数组中按字母顺序排列它们。关于这个挑战的问题之前已经出现过,但是我在SO上没有找到我的具体问题,所以如果是重复问题,我很抱歉。

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

虽然这样做可以解决问题,但我正在尝试弄清如何按字母顺序排序数组而不区分大小写。 这很难理解。

我了解到strcasecmp方法,但它似乎是用于比较特定字符串而不是字符串数组的方法。

到目前为止,我一直在尝试类似以下的内容:

wordlist.to_s.downcase.to_a.sort!

此外,它不仅看起来不好,而且由于Ruby 2.0不允许将字符串转换为数组等多种原因而无法使用。


翻译:哎呀!忘了提一下。我知道可以将整个数组转换为字符串后将其全部转换为小写,但我希望以输入时的大小写形式返回这些值。 - user2608684
3个回答

118

怎么样:

wordlist.sort_by { |word| word.downcase }

甚至更短:

wordlist.sort_by(&:downcase)

4
这是一个提示:你正试图对一个数组进行操作,因此请在谷歌搜索“ruby 数组”。通常第一个结果会是类:XXX (Ruby)。这是你所搜索的类的 Ruby 文档。点击链接,开始浏览左侧列出的方法。如果找不到想要的方法,下一个要检查的地方是左侧的“Included Modules”模块中。点击可枚举模块(Enumerable),并查看其中的方法。在可枚举模块(Enumerable)中,你将找到sort_by()方法。 - 7stud
10
对于像 mapsort_byselect 等方法,如果你要对每个元素执行一个块,且该块只是在每个元素上调用一个方法,则有一些语法糖可用。它看起来像这样:wordlist.sort_by(&:downcase) - Luke Griffiths

4

通常情况下,对于计算简单的键,sort_by 不是很高效。更有效的比较方法是使用带有块的 sort,并将默认比较运算符 <=> 替换为 casecmp。

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

如果想了解如何提高程序效率,可以查看官方 Ruby 文档中 sort_by 方法的详细介绍:http://www.ruby-doc.org/core-2.1.2/Enumerable.html#method-i-sort_by


2
恐怕 casecmp 不像 ruby-doc 的例子一样简单,那样只是返回对象本身。您可以自己试试: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 快了40%。 - Kelvin

0

我在我的 Ruby 编程训练营中也有同样的问题。以下是对我有效的方法:

puts "Type in a sentence."
sentence = gets.chomp.downcase
puts sentence.split(" ").sort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接