Я пытаюсь выяснить способ проверки существования значения в массиве без перебора массива.
Я читаю файл для параметра. У меня длинный список параметров, с которыми я не хочу иметь дело. Я поместил эти нежелательные параметры в массив @badparams
.
Я хочу прочитать новый параметр и, если он не существует @badparams
, обработать его. Если он существует @badparams
, перейдите к следующему прочтению.
perl
arrays
comparison
Мел
источник
источник
Ответы:
Просто превратите массив в хеш:
Вы также можете добавить больше (уникальных) параметров в список:
А позже вернем список (уникальных) параметров:
источник
1
снова.Лучшее общее назначение - особенно короткие массивы (1000 элементов или меньше) и кодеры, которые не уверены, какие оптимизации лучше всего соответствуют их потребностям.
Как уже упоминалось, grep проходит через все значения, даже если первое значение в массиве совпадает. Это правда, однако grep все еще чрезвычайно быстр для большинства случаев . Если вы говорите о коротких массивах (менее 1000 элементов), то большинство алгоритмов в любом случае будут довольно быстрыми. Если вы говорите об очень длинных массивах (1 000 000 элементов), то grep работает достаточно быстро независимо от того, является ли элемент первым, средним или последним в массиве.
Случаи оптимизации для более длинных массивов:
Если ваш массив отсортирован , используйте «бинарный поиск».
Если один и тот же массив неоднократно ищется , сначала скопируйте его в хеш, а затем проверьте хеш. Если проблема связана с памятью, переместите каждый элемент из массива в хеш. Больше памяти эффективно, но разрушает исходный массив.
Если одни и те же значения неоднократно ищутся в массиве, лениво создайте кеш. (так как каждый элемент ищется, сначала проверьте, был ли результат поиска сохранен в постоянном хэше. Если результат поиска не найден в хэше, то ищите массив и поместите результат в постоянный хеш, чтобы в следующий раз мы найдите его в хэше и пропустите поиск).
Примечание: эти оптимизации будут быстрее только при работе с длинными массивами. Не переусердствуйте.
источник
Вы можете использовать функцию smartmatch в Perl 5.10 следующим образом:
Для поиска литерального значения, сделанного ниже, добьется цели.
Для скалярного поиска выполнение ниже будет работать как выше.
Для встроенного массива, выполняемого ниже, будет работать, как указано выше.
В Perl 5.18 smartmatch помечен как экспериментальный, поэтому вам нужно отключить предупреждения, включив экспериментальную прагму, добавив ниже в ваш скрипт / модуль:
В качестве альтернативы, если вы хотите избежать использования smartmatch - тогда, как сказал Аарон, используйте:
источник
use experimental 'smartmatch'
рекомендуется. Поскольку у меня есть контроль над моей версией Perl (внутренняя система), я используюno warnings 'experimental::smartmatch';
оператор.В этом блоге обсуждаются лучшие ответы на этот вопрос.
Вкратце, если вы можете установить модули CPAN, то наиболее читаемые решения:
или
Тем не менее, более распространенная идиома:
Но, пожалуйста, не используйте эту
first()
функцию! Он не выражает цели вашего кода вообще. Не используйте~~
оператор «Smart match»: он сломан. И не используйтеgrep()
ни решение с хешем: они перебирают весь список.any()
остановится, как только найдет вашу ценность.Проверьте сообщение в блоге для более подробной информации.
источник
use List::Util qw(any);
.List::Util
находится в основных модулях .Метод 1: grep (может быть осторожен, хотя ожидается, что значение будет регулярным).
Старайтесь избегать использования
grep
, если смотрите на ресурсы.Способ 2: линейный поиск
Способ 3: использовать хеш
Способ 4: Smartmatch
(добавлено в Perl 5.10, помечено как экспериментальное в Perl 5.18).
Способ 5: использовать модуль
List::MoreUtils
источник
тест @ eakssjo нарушен - измеряет создание хэшей в цикле против создания регулярных выражений в цикле. Фиксированная версия (плюс я добавил
List::Util::first
иList::MoreUtils::any
):И результат (это за 100_000 итераций, в десять раз больше, чем в ответе @ eakssjo):
источник
Несмотря на то, что его удобно использовать, кажется, что решение для преобразования в хэш требует довольно большой производительности, что было проблемой для меня.
Результат бенчмарк-теста:
источник
List::Util::first
быстрее, поскольку оно прекращает итерацию, когда находит совпадение.grep
он значительно медленнее, чем создание хэша и поиск, так как первым является O (n), а последним O (1). Просто сделайте создание хеша только один раз (вне цикла) и предварительно вычислите регулярное выражение только для измерения методов ( см. Мой ответ ).@files - это существующий массив
/^2[\d].[\d][A-za-z]?/ = vaues начиная с 2, здесь вы можете поместить любое регулярное выражение
источник
Вы, конечно, хотите хеш здесь. Поместите неверные параметры в качестве ключей в хеш, затем решите, существует ли конкретный параметр в хэше.
Если вы действительно заинтересованы в этом с массивом, посмотрите на
List::Util
илиList::MoreUtils
источник
Есть два способа сделать это. Вы можете использовать бросок значений в хеш для таблицы поиска, как предложено в других публикациях. (Я добавлю еще одну идиому.)
Но если это данные, состоящие в основном из символов слова и не слишком много мета, вы можете поместить их в чередование регулярных выражений:
Это решение должно быть настроено для типов «плохих ценностей», которые вы ищете. И опять же, это может быть совершенно неуместно для определенных типов строк, поэтому будьте осторожны с emptor .
источник
@bad_param_lookup{@bad_params} = ()
, но вам нужно будет использоватьexists
для проверки членства.Вы можете проверить постоянство числовых ведущих пробелов
источник