2
\$\begingroup\$

What would be the most efficient way to write the following code in Perl:

       my $index = 0;
       foreach ( @spec ) {
          if ( $module =~ m/$_/ ) {
         splice(@spec, $index, 0, $module);
             last;         
          }
          $index++;
       }

This works fine but just seems a little wordy. The idea is that where I find a match for $module in the array I add an entry. I want to keep the array in a certain order and sorted.

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

You want "more efficient wordiness"??? I presume you're not asking for golfing, but for code that's more readable from conciseness.

@spec = map { $_ eq $module ? ($_, $_) : $_ } @spec;
\$\endgroup\$
1
  • \$\begingroup\$ Yeah this is perfect! \$\endgroup\$
    – evolution
    May 10, 2013 at 15:25
1
\$\begingroup\$
  1. You manually increment the $index. Just loop over the indices instead:

    for my $index (0 .. $#spec) {
      if ($module =~ /$spec[$index]/) {
        splice @spec, $index, 0, $module;
        last;
      }
    }
    

    On newer perls (v12+) you can use each on arrays:

    use 5.012;
    while(my ($i, $str) = each @spec) {
       if ($module =~ /$str/) {
         splice @spec, $i, 0, $module;
         keys @spec; # reset the `each` iterator
         last;
       }
    }
    
  2. If the values in @spec are not regexes, but just plain strings, and iff you want to test that $module contains the string in $spec[$index], then you could use index for better efficiency.

    if (-1 != index $module, $spec[$index]) { ... }
    

    This also won't treat characters like \[]()?+* as metacharacters any more. This would be similar to /\Q$spec[$index]\E/ (see quotemeta function), but more efficient

    If you actually want to apply the string as a regex, this point is moot.

\$\endgroup\$
2
  • \$\begingroup\$ Ad. #1: I'd use foreach loop and increment counter manyally just like OP, so it's rather subjective (although each would be my choice if all production code run on >= v5.12). \$\endgroup\$ May 10, 2013 at 14:36
  • \$\begingroup\$ It would probably be safer to reset the iterator before you modify the array. \$\endgroup\$
    – ikegami
    May 13, 2013 at 1:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.