Comparing Multiple Lines in Perl

I have my code:

if ( $var eq "str1" || $var eq "str2" || $var eq "str3" ) { ... } 

Is there any way to optimize this. I need something like:

 if ( $var eq ["str1" || "str2" || "str3"] ) {...} 
+7
source share
5 answers

Depending on the contents of the lines, the regex is quite convenient:

 if ($var =~ /^(str1|str2|str3)$/) { … } 

Otherwise, you can grep over the list:

 if (grep { $var eq $_ } qw{str1 str2 str3}) { … } 
+13
source

In Perl 5.10 or higher:

 if ($var ~~ [qw( str1 str2 str3 )]) { ...} 

The ~~ operator performs a smart match between its arguments.

+14
source
  • Use List::MoreUtils qw{any}

     use List::MoreUtils qw{any}; if ( any { $var eq $_ } 'str1', 'str2', 'str3' ) { ... } 

    This may be faster than using grep , because List::MoreUtils::any ends earlier when it finds a match, whereas grep can make a complete list of matches. I say “maybe” because Perl could optimize if (grep ... Maybe it isn’t. But List::MoreUtils::any ends earlier, and it is more descriptive than the if (grep ...

  • Make a hash that has the keys of all the strings you want to match

     my %matcher; @matcher{qw{str1 str2 str3}} = (); if ( exists $matcher{$var} ) { ... } 

    This has a lack of tuning time and the cost of memory used for the hash, but the advantage is that the match time is more like O (log N). Therefore, if you have many different $var values ​​that you want to check, then this can be faster overall.

  • Make regex matching all your lines

     if ( $var =~ m/^str[123]$/so ) { ... } 

    OK, so it's ok if your lines are literally qw{str1 str2 str3} , but what if it's a list of arbitrary lines?

    You can use Regexp :: Assemble to combine a list of regular expressions into one optimized regular expression.

+2
source

For a list of fixed strings, convert the list to a hash. This is especially useful if you intend to check your list more than once, and if your list grows larger.

 %on_my_list = map {; $_ => 1 } 'str1', 'str2', 'str3', ...; if ($on_my_list{$var}) { ... } 
+1
source

I'm half-noise, but this will do:

 use Quantum::Superpositions; if ($x == any($a, $b, $c)) { ... } 

See also Perl Monks thread

0
source

All Articles