MISE à JOUR:
sur la base des résultats des discussions à this question, en fonction de votre intention/critères de ce qui constitue « ne pas utiliser une boucle », la solution map
ci-dessous (voir "Option n ° 1) peut être le plus solution concise, à condition que vous ne consi der map
une boucle (la version courte des réponses est: c'est une boucle en ce qui concerne l'implémentation/la performance, ce n'est pas une boucle du point de vue théorique du langage).
En supposant que vous ne vous inquiétez pas si vous obtenez « 3 » ou « Sony » comme la réponse, vous pouvez le faire sans une boucle dans un cas simple, en construisant une expression régulière avec « ou » logique (|
) à partir du tableau, comme ceci:
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";
Résultat de mon essai: Sony
l'expression régulière (une fois la variable $combined_search
est interpolée par Perl) ta ke le formulaire /(Canon|HP|Sony)/
qui est ce que vous voulez.
Cela ne fonctionnera pas en l'état si l'une des chaînes contenant des caractères spéciaux regex (tels que |
ou )
) - dans ce cas, vous devez les échapper
NOTE: Personnellement, je considère cela un peu tricher , parce que pour mettre en œuvre join()
, Perl lui-même doit faire une boucle quelque part à l'intérieur de l'interpètre. Donc, cette réponse peut ne pas satisfaire votre désir de rester sans boucle, selon que vous vouliez éviter une boucle pour des considérations de performance, d'avoir un code plus propre ou plus court.
P.S. Pour obtenir "3" au lieu de "Sony", vous devrez utiliser une boucle - soit de façon évidente, en faisant 1 match dans une boucle en dessous de tout cela; ou en utilisant une bibliothèque qui vous évite d'écrire la boucle vous-même mais qui aura une boucle sous l'appel.
Je vais fournir 3 solutions alternatives.
# 1 option: - mon préféré.Utilise "carte", que je considère personnellement encore une boucle:
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: Utilise une boucle cachée derrière une belle méthode de bibliothèque 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 Option: Voici le chemin de la boucle évidente:
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.
Perl n'est pas vraiment magique. C'est juste un exemple de la technologie avancée d'Arthur C. Clarke qui est indiscernable de la magie :) Puis encore, il y a tout ce que je considère personnellement comme le vaudou :( – DVK
Quoi de neuf avec cette boucle déteste ces derniers temps? Si vous avez besoin de faire quelque chose Sur une liste d'éléments, vous devez les boucler d'une façon ou d'une autre.Vous ne pouvez pas utiliser explicitement 'for' ou' while' mais à la fin de la journée, même la solution la plus ésotérique utilisera un cycle quelconque sous le capot. –
@kemp - Y at-il eu d'autres questions anti-boucle récemment que j'ai raté? – DVK