不区分大小写的数组#包括?

我想知道什么是最好的方式来使String.include? 方法忽略大小写。 目前我正在做以下。 有什么build议么? 谢谢!

 a = "abcDE" b = "CD" result = a.downcase.include? b.downcase 

编辑:如何Array.include? 。 数组的所有元素都是string。

概要

如果你只是对一个数组testing一个单词,或者你的数组内容经常变化,最快的答案是Aaron的:

 array.any?{ |s| s.casecmp(mystr)==0 } 

如果要对静态数组testing多个单词,最好使用farnoy答案的变体:创build一个包含全部小写字母版本的数组副本,并使用include? 。 (这里假定你可以用内存来创build你的数组的变异副本。)

 # Do this once, or each time the array changes downcased = array.map(&:downcase) # Test lowercase words against that array downcased.include?( mystr.downcase ) 

更好的是,从你的数组中创build一个Set

 # Do this once, or each time the array changes downcased = Set.new array.map(&:downcase) # Test lowercase words against that array downcased.include?( mystr.downcase ) 

我下面的原始答案是一个非常差的表演者,一般不合适。

基准

以下是在一个稍微超过100,000个单词的数组中search1000个单词的基准,其中500个单词将被find,500个单词不会被search到。

  • “正则expression式”文本是我的答案在这里,使用any?
  • 'casecmp'testing是阿龙的答案,使用any? 从我的评论。
  • “arrays”testing是farnoy的答案,为1,000次testing中的每一次重新创build一个新的arrays。
  • 'downonce'testing是farnoy的答案,但是只需预先创build一次查找数组。
  • 'set_once'testing是在testing之前从downcasedstring数组创build一个Set
  user system total real regex 18.710000 0.020000 18.730000 ( 18.725266) casecmp 5.160000 0.000000 5.160000 ( 5.155496) downarray 16.760000 0.030000 16.790000 ( 16.809063) downonce 0.650000 0.000000 0.650000 ( 0.643165) set_once 0.040000 0.000000 0.040000 ( 0.038955) 

如果你可以创build一个单一的数组downcased副本来执行许多查找,farnoy的答案是最好的(假设你必须使用一个数组)。 如果你可以创build一个Set ,尽pipe如此。

如果你喜欢,请检查基准代码 。


原始答复

(原来说我)会亲自创build一个不区分大小写的正则expression式(对于string文字),并使用它:

 re = /\A#{Regexp.escape(str)}\z/i # Match exactly this string, no substrings all = array.grep(re) # Find all matching strings… any = array.any?{ |s| s =~ re } # …or see if any matching string is present 

使用any? 可以比grep稍微快一点,因为只要find一个匹配项就可以退出循环。

对于数组,请使用:

 array.collect {|el| el.downcase }.include? string 

正则expression式非常缓慢,应该避免。

你可以使用casecmp来做你的比较,忽略大小写。

 "abcdef".casecmp("abcde") #=> 1 "aBcDeF".casecmp("abcdef") #=> 0 "abcdef".casecmp("abcdefg") #=> -1 "abcdef".casecmp("ABCDEF") #=> 0 
 class String def caseinclude?(x) a.downcase.include?(x.downcase) end end 

my_array.map {|!c请| c.downcase.strip}

哪里map! 更改my_array,而是返回一个新的数组。

在我的情况下,你的例子对我来说不起作用。 我实际上正在寻找这样做的任何“子串”。

这是我的testing案例。

 x = "<TD>", "<tr>", "<BODY>" y = "td" x.collect { |r| r.downcase }.include? y => false x[0].include? y => false x[0].downcase.include? y => true 

您的案例与一个确切的不区分大小写的匹配。

 a = "TD", "tr", "BODY" b = "td" a.collect { |r| r.downcase }.include? b => true 

我仍然在这里尝试其他的build议。

—编辑后插入—

我find了答案。 感谢Drew Olsen

 var1 = "<TD>", "<tr>","<BODY>" => ["<TD>", "<tr>", "<BODY>"] var2 = "td" => "td" var1.find_all{|item| item.downcase.include?(var2)} => ["<TD>"] var1[0] = "<html>" => "<html>" var1.find_all{|item| item.downcase.include?(var2)} => []