Comparing Multiple Strings In Perl

后端 未结 5 1632
广开言路
广开言路 2021-01-17 23:15

I have my code like this:

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

Is there anyways to optimize this. I want

相关标签:
5条回答
  • 2021-01-17 23:42
    1. Use List::MoreUtils qw{any}

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

      This might be faster than using grep because List::MoreUtils::any finishes early when it finds a match whereas grep might build a complete list of matches. I say 'might' because Perl could conceivably optimise if (grep .... It might not. But List::MoreUtils::any does finish early, and it's more descriptive than the if (grep ... idiom.

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

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

      This has the disadvantage of a set-up time and the cost of the memory used for the hash, but the advantage is that the match time is more like O(log N). So if you have lots of different values of $var that you want to test then it could be faster overall.

    3. Make a regex that matches all of your strings

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

      OK, so this is fine if your strings are literally qw{str1 str2 str3}, but what if it is a list of arbitrary strings?

      You could use Regexp::Assemble to fuse together a list of regexps into a single optimised regexp.

    0 讨论(0)
  • 2021-01-17 23:51

    For a list of fixed strings, convert your list to a hash. This is especially useful if you are going to check against your list several times, and if your list gets larger.

    %on_my_list = map {; $_ => 1 } 'str1', 'str2', 'str3', ...;
    
    if ($on_my_list{$var}) { ... }
    
    0 讨论(0)
  • 2021-01-17 23:53

    I'm semi-joking, but this will do it:

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

    See also this Perl Monks thread

    0 讨论(0)
  • 2021-01-17 23:58

    In Perl 5.10 or better:

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

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

    0 讨论(0)
  • 2021-01-18 00:07

    Depending on the contents of the strings, a regex is quite convenient:

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

    Failing that, you can grep over a list:

    if (grep { $var eq $_ } qw{str1 str2 str3}) { … }
    
    0 讨论(0)
提交回复
热议问题