Резюме
Если вы собираетесь проверять только одно слово в массиве или если содержимое вашего массива часто меняется, самый быстрый ответ - Аарон:
array.any?{ |s| s.casecmp(mystr)==0 }
Если вы собираетесь тестировать много слов на статическом массиве, гораздо лучше использовать вариант ответа фарной: создайте копию массива, содержащую строчные версии ваших слов, и используйте include?
. (Это предполагает, что вы можете сэкономить память для создания измененной копии вашего массива.)
# Do this once, or each time the array changes
downcased = array.map(&:downcase)
# Test lowercase words against that array
downcased.include?( mystr.downcase )
Еще лучше, создайте 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 )
Мой оригинальный ответ ниже очень плохой и, как правило, не подходит.
Ориентиры
Ниже приведены критерии для поиска 1000 слов со случайным регистром в массиве из чуть более 100 000 слов, где 500 слов будут найдены, а 500 - нет.
- Текст 'regex' - мой ответ, используя
any?
.
- Тест 'casecmp' - это ответ Аррона, используя
any?
из моего комментария.
- Тест 'downarray' - это ответ Фарной, воссоздавая новый массив в нижнем регистре для каждого из 1000 тестов.
- Тест 'downonce' - это ответ Фарной, но он предварительно создает массив поиска только один раз.
- Тест '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)
Если вы можете создать единственную копию массива в нижнем регистре один раз, чтобы выполнить множество поисков, ответ фарной будет лучшим (если вы должны использовать массив). Если вы можете создать Set
, сделайте это.
Если хотите, проверьте код теста .
Оригинальный ответ
I (изначально говорилось, что я) лично создаст без учета регистра регулярное выражение (для строкового литерала) и использует это:
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
, поскольку оно может выйти из цикла, как только найдет одно совпадение.