tengo mi código como este:comparar cadenas múltiples en Perl
if ($var eq "str1" || $var eq "str2" || $var eq "str3")
{
...
}
¿Existe de todos modos para optimizar este. Quiero algo como:
if ($var eq ["str1" || "str2" || "str3"]) {...}
tengo mi código como este:comparar cadenas múltiples en Perl
if ($var eq "str1" || $var eq "str2" || $var eq "str3")
{
...
}
¿Existe de todos modos para optimizar este. Quiero algo como:
if ($var eq ["str1" || "str2" || "str3"]) {...}
En función de los contenidos de las cadenas, una expresión regular es muy conveniente:
if ($var =~ /^(str1|str2|str3)$/) { … }
De no ser así, puede grep más de una lista:
if (grep { $var eq $_ } qw{str1 str2 str3}) { … }
muchas gracias ... La primera expresión funcionó pero con los corchetes eliminados: if ($ var = ~/^ str1 | str2 | str3 $ /) – sundar
@ user988967, No, no es así. Sin los parens, coincidirá con 'str1A',' Astr2A' y 'Astr3'. – ikegami
@ikegami, sí, estás en lo cierto. gracias .. Una consulta más. Estoy usando "use strict" en la parte superior de mi código. Entonces, ¿me aconsejaría usar "?:" – sundar
En Perl 5.10 o mejor:
if ($var ~~ [qw(str1 str2 str3)]) { ...}
El operador ~~
hace un smart match entre sus argumentos.
+1; No tenía idea de que este operador existe. –
@MarceloCantos: *** "El operador de Smartmatch es experimental y su comportamiento está sujeto a cambios". *** Recomiendo que lo evite – Borodin
@Borodin: generalmente evito Perl, pero +1 para el cara a cara de todos modos. –
Uso List::MoreUtils qw{any}
use List::MoreUtils qw{any};
if (any { $var eq $_ } 'str1', 'str2', 'str3') {
...
}
Esto podría ser más rápido que usar grep
PORQUE List::MoreUtils::any
acabados temprana cuando se encuentra una coincidencia mientras que grep
podría construir una lista completa de los partidos. Digo 'podría' porque Perl podría posiblemente optimizar if (grep ...
. Puede que no. Pero List::MoreUtils::any
termina temprano, y es más descriptivo que el idioma if (grep ...
.
Hacer un hash que tiene llaves de todas las cadenas que desea hacer coincidir
my %matcher;
@matcher{qw{str1 str2 str3}} =();
if (exists $matcher{$var}) {
...
}
Esto tiene el inconveniente de un tiempo de preparación y el costo de la memoria utilizada para el hash, pero la ventaja es que el tiempo de coincidencia es más como O (log N). Entonces, si tiene muchos valores diferentes de $var
que desea probar, podría ser más rápido en general.
Hacer una expresión regular que coincide con todas sus cadenas
if ($var =~ m/^str[123]$/so) {
...
}
bien, así que esto está muy bien si sus cadenas son, literalmente, qw{str1 str2 str3}
, pero lo que si es una lista de cadenas arbitrarias?
Puede usar Regexp::Assemble para fusionar una lista de expresiones regulares en una sola expresión regular optimizada.
[Regexp :: Assemble] (http://p3rl.org/Regexp::Assemble) no es necesario en los Perls más nuevos, ya que ahora las expresiones regulares tienen [Optimización de Trie] (http://perldoc.perl.org/perl5100delta.html # Trie-optimization-of-literal-string-alternations). –
estoy semi-broma, pero esto lo hará:
use Quantum::Superpositions;
if ($x == any($a, $b, $c)) { ... }
Ver también este Perl Monks thread
Para una lista de cadenas fijas, convertir su lista a un hash. Esto es especialmente útil si va a consultar su lista varias veces y si su lista aumenta.
%on_my_list = map {; $_ => 1 } 'str1', 'str2', 'str3', ...;
if ($on_my_list{$var}) { ... }
Si con "optimizar" quiere decir "hacerlo ir más rápido", la primera versión es óptima (si ordena las cuerdas para que la más probable esté al frente). – Mat