ОБНОВЛЕНИЕ:
На основании результатов обсуждения в этот вопрос , в зависимости от ваших намерений / критериев того, что составляет "не использовать цикл",Решение на основе map
ниже (см. « Option # 1 ) может быть наиболее кратким решением, при условии, что вы не считаете map
циклом (краткая версия ответов: это циклчто касается реализации / производительности, это не цикл с теоретической точки зрения языка).
Предполагая, что вам все равно, получите ли вы «3» или «Sony» в качестве ответа, вы можете сделать это без цикла в простом случае, построив регулярное выражение с "или" логикой (|
) из массива, например:
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
my $combined_search = join("|",@strings);
my @which_found = ($search_in =~ /($combined_search)/);
print "$which_found[0]\n";
Результат из моеготестовый прогон: Sony
Регулярное выражение (после интерполяции переменной Perl $combined_search
) примет форму /(Canon|HP|Sony)/
, что вам нужно.
Это НЕ будет работатькак есть, если любая из строк содержит специальные символы регулярного выражения (например, |
или )
) - в этом случае вам необходимо их избежать
ПРИМЕЧАНИЕ : лично я считаю это несколько обманом, потому что для реализации join()
сам Perl должен выполнить цикл где-то внутриинтерпретатор.Таким образом, этот ответ может не удовлетворить ваше желание оставаться без цикла, в зависимости от того, хотите ли вы избежать цикла из соображений производительности, чтобы иметь более чистый или более короткий код.
PS Чтобы получить «3»вместо «Sony» вам придется использовать цикл - либо очевидным образом, выполнив 1 совпадение в цикле под всем этим;или используя библиотеку, которая избавляет вас от написания цикла самостоятельно, но под вызовом будет цикл.
Я предоставлю 3 альтернативных решения.
# 1 опция: - мое любимое.Использует «map», который я лично до сих пор считаю циклом:
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
my $combined_search = join("|",@strings);
my @which_found = ($search_in =~ /($combined_search)/);
print "$which_found[0]\n";
die "Not found" unless @which_found;
my $strings_index = 0;
my %strings_indexes = map {$_ => $strings_index++} @strings;
my $index = 1 + $strings_indexes{ $which_found[0] };
# Need to add 1 since arrays in Perl are zero-index-started and you want "3"
# 2 option : Использует цикл, скрытый за красивым методом библиотеки CPAN:
use List::MoreUtils qw(firstidx);
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
my $combined_search = join("|",@strings);
my @which_found = ($search_in =~ /($combined_search)/);
die "Not Found!"; unless @which_found;
print "$which_found[0]\n";
my $index_of_found = 1 + firstidx { $_ eq $which_found[0] } @strings;
# Need to add 1 since arrays in Perl are zero-index-started and you want "3"
# 3 опция: Вот очевидный путь петли:
my $found_index = -1;
my @strings = ("Canon", "HP", "Sony");
my $search_in = "Sony's Cyber-shot DSC-S600";
foreach my $index (0..$#strings) {
next if $search_in !~ /$strings[$index]/;
$found_index = $index;
last; # quit the loop early, which is why I didn't use "map" here
}
# Check $found_index against -1; and if you want "3" instead of "2" add 1.