不区分大小写的数组#include?

Jus*_*ner 46 ruby string

我想知道什么是使String.include?方法忽略大小写的最佳方法.目前我正在做以下事情.有什么建议?谢谢!

a = "abcDE"
b = "CD"
result = a.downcase.include? b.downcase
Run Code Online (Sandbox Code Playgroud)

编辑:怎么样Array.include?.数组的所有元素都是字符串.

Phr*_*ogz 58

摘要

如果您只是针对数组测试单个单词,或者数组内容经常更改,那么最快的答案是Aaron:

array.any?{ |s| s.casecmp(mystr)==0 }
Run Code Online (Sandbox Code Playgroud)

如果你要针对静态数组测试很多单词,那么使用farnoy答案的变体要好得多:创建一个包含单词全小写版本的数组副本,然后使用include?.(这假设您可以节省内存来创建阵列的变异副本.)

# Do this once, or each time the array changes
downcased = array.map(&:downcase)

# Test lowercase words against that array
downcased.include?( mystr.downcase )
Run Code Online (Sandbox Code Playgroud)

更好的是,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 )
Run Code Online (Sandbox Code Playgroud)

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

基准

以下是使用随机套管查找1,000个单词的基准测试,其中包含超过100,000个单词的数组,其中500个单词将被找到而500个单词将不会被找到.

  • 使用"正则表达式"文本是我的答案any?.
  • 根据any?我的评论,'casecmp'测试是Arron的答案.
  • 'downarray'测试是farnoy的答案,为1,000个测试中的每个测试重新创建一个新的下层阵列.
  • 'downonce'测试是farnoy的答案,但只预先创建一次查找数组.
  • 'set_once'测试是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)
Run Code Online (Sandbox Code Playgroud)

如果您可以创建一个单个下载的数组副本一次以执行许多查找,farnoy的答案是最好的(假设您必须使用数组).Set但是,如果你可以创建一个,那就去做吧.

如果您愿意,请检查基准测试代码.


原始答案

(最初说我)将亲自创建一个不区分大小写的正则表达式(对于字符串文字)并使用:

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
Run Code Online (Sandbox Code Playgroud)

一旦找到单个匹配,使用any?可以稍微快于grep它可以退出循环.

  • 在这看到一些有趣的答案,没有意识到我是最快的一个.感谢您比较所有这些. (2认同)

far*_*noy 11

对于数组,请使用:

array.map(&:downcase).include?(string)
Run Code Online (Sandbox Code Playgroud)

Regexps非常慢,应该避免.

  • 我必须有点吃我的话。:) 如添加到我的答案中的基准测试所示,为每个测试重新创建小写数组的执行速度仅比我的基于正则表达式的解决方案慢一点。但是,如果需要针对同一个数据集进行多次查找,那么如果您预先创建了 `array.map(&:downcase)` 并对其进行测试,那么这个答案是最好的。 (2认同)
  • 那么,我猜"谢谢"是有序的;) (2认同)

Aar*_*ver 7

您可以使用casecmp进行比较,忽略大小写.

"abcdef".casecmp("abcde")     #=> 1
"aBcDeF".casecmp("abcdef")    #=> 0
"abcdef".casecmp("abcdefg")   #=> -1
"abcdef".casecmp("ABCDEF")    #=> 0
Run Code Online (Sandbox Code Playgroud)

  • 使用[`array.any?{| s | s.casecmp("mystr")== 0}`](http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-any-3F). (4认同)