ruby 不区分大小写的数组#include?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9333952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Case-insensitive Array#include?
提问by Just a learner
I want to know what's the best way to make the String.include?methods ignore case. Currently I'm doing the following. Any suggestions? Thanks!
我想知道使String.include?方法忽略大小写的最佳方法是什么。目前我正在做以下事情。有什么建议?谢谢!
a = "abcDE"
b = "CD"
result = a.downcase.include? b.downcase
Edit:
How about Array.include?. All elements of the array are strings.
编辑:怎么样Array.include?。数组的所有元素都是字符串。
回答by Phrogz
Summary
概括
If you are only going to test a single word against an array, or if the contents of your array changes frequently, the fastest answer is Aaron's:
如果您只想针对数组测试单个单词,或者数组的内容经常更改,那么最快的答案是 Aaron:
array.any?{ |s| s.casecmp(mystr)==0 }
If you are going to test many words against a static array, it's far better to use a variation of farnoy's answer: create a copy of your array that has all-lowercase versions of your words, and use include?. (This assumes that you can spare the memory to create a mutated copy of your array.)
如果要针对静态数组测试多个单词,最好使用 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 )
Even better, create a Setfrom your array.
更好的是,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 )
My original answer below is a very poor performer and generally not appropriate.
我在下面的原始答案是一个非常糟糕的表现,通常不合适。
Benchmarks
基准
Following are benchmarks for looking for 1,000 words with random casing in an array of slightly over 100,000 words, where 500 of the words will be found and 500 will not.
以下是在略高于 100,000 个单词的数组中查找 1,000 个随机大小写单词的基准,其中 500 个单词会被找到,500 个不会。
- The 'regex' text is my answer here, using
any?. - The 'casecmp' test is Arron's answer, using
any?from my comment. - The 'downarray' test is farnoy's answer, re-creating a new downcased array for each of the 1,000 tests.
- The 'downonce' test is farnoy's answer, but pre-creating the lookup array once only.
- The 'set_once' test is creating a
Setfrom the array of downcased strings, once before testing.
- “正则表达式”文本是我在这里的答案,使用
any?. - 'casecmp' 测试是 Arron 的答案,使用
any?我的评论。 - '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)
If you can create a single downcased copy of your array once to perform many lookups against, farnoy's answer is the best (assuming you mustuse an array). If you can create a Set, though, do that.
如果您可以一次创建数组的单个缩小副本来执行多次查找,farnoy 的答案是最好的(假设您必须使用数组)。Set但是,如果您可以创建一个,请执行此操作。
If you like, examine the benchmarking code.
如果您愿意,请检查基准测试代码。
Original Answer
原答案
I (originally said that I)would personally create a case-insensitive regex (for a string literal) and use that:
我(最初说我)会亲自创建一个不区分大小写的正则表达式(用于字符串文字)并使用它:
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
Using any?can be slightly faster than grepas it can exit the loop as soon as it finds a single match.
使用any?可能比grep它在找到单个匹配项后立即退出循环稍快。
回答by farnoy
For an array, use:
对于数组,请使用:
array.map(&:downcase).include?(string)
Regexps are very slow and should be avoided.
正则表达式非常慢,应避免使用。
回答by Aaron McIver
回答by johannes
class String
def caseinclude?(x)
a.downcase.include?(x.downcase)
end
end
回答by Konda Reddy R
my_array.map!{|c| c.downcase.strip}
my_array.map!{|c| c.downcase.strip}
where map!changes my_array, mapinstead returns a new array.
其中map!更改 my_array,map而是返回一个新数组。
回答by 6ft Dan
To farnoy in my case your example doesn't work for me. I'm actually looking to do this with a "substring" of any.
在我的情况下,你的例子对我不起作用。我实际上希望用 any 的“子字符串”来做到这一点。
Here's my test case.
这是我的测试用例。
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
Your case works with an exact case-insensitive match.
您的案例适用于完全不区分大小写的匹配。
a = "TD", "tr", "BODY"
b = "td"
a.collect { |r| r.downcase }.include? b
=> true
I'm still experimenting with the other suggestions here.
我仍在尝试这里的其他建议。
---EDIT INSERT AFTER HERE---
---在此之后编辑插入---
I found the answer. Thanks to 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)}
=> []

