in reply to How to count substitutions on an array

$count = () = s/// is a single expression that repeats for each element in @array. Apparently the final element in @array matches but once. If there were two patterns in the final element of @array matching your pattern, then the could would be 2. On each iteration of your for loop the expression is evaluated against a new $_ input, and $count is replaced. You do not employ an accumulator of any kind.

If you wanted to do this as a single line of code you could do this:

do {$count = () = $s/PATTERN/REPLACEMENT/g; $acc += $count} for @array +;

Update: Apparently it's not my day. See below. Thanks AnomalousMonk.

In the end, $acc should contain your total number of matches.

Keep in mind that your /e modifier is probably wrong, and maybe a risk. If the replacement comes from somewhere outside of your control, it could be used to pass a destructive command through the Perl interpreter.


Dave

Replies are listed 'Best First'.
Re^2: How to count substitutions on an array
by AnomalousMonk (Archbishop) on Aug 14, 2016 at 01:08 UTC
    do {$count = () = $s/PATTERN/REPLACEMENT/g; $acc += $count} for @array;

    But  s/// returns the number of substitutions made (or the empty string if none), so when list-ified this number (or the empty string) will always be a single-elemment list (update: which in scalar context will always be a  $count of 1), so the  $acc total will always be the number of elements of the  @array array.

    c:\@Work\Perl>perl -wMstrict -le "my @array = qw(PAT PATxPATxPAT PATxPATxPATxPATxPAT xxxxx); ;; my $acc; do { my $count = () = s/PAT/REP/g; $acc += $count; } for @array; ;; print qq{\$acc: $acc \@array: (@array)}; " $acc: 4 @array: (REP REPxREPxREP REPxREPxREPxREPxREP xxxxx)


    Give a man a fish:  <%-{-{-{-<

      Thanks. You caught me!

      Here are some idioms that could be preferable:

      use strict; use warnings; my @data = qw(foozbar foozball zoobeezoobedo); my $acc = 0; do { my $count = s/o/*/g; $acc+=$count; } for @data; print "$acc\n"; # But the above really can just boil down to: my $count; $count += s/\*/o/g for @data; print "$count\n"; # List::Util's reduce is always fun. use List::Util 'reduce'; my $total = reduce {$a += $b =~ s/o/*/g} 0, @data; print "$total\n";

      Hope this helps (and thanks again for catching the error).


      Dave