http://qs1969.pair.com?node_id=82140


in reply to Re: Replacing a given character starting with the xth occurence in a string
in thread Replacing a given character starting with the xth occurence in a string

I can see that you put some effort in this program, so I have ++'d your post. Now I'll offer some comments as constructive criticism, and a rewriting of your program to show some more Perlish ways of doing things: So here's my first rewrite of the main section of your program:
@q = split (//, $p); foreach (@q) { $count++ if $_ eq $matchchar; if ($_ eq $matchchar && ($count >= $nummatch)) { $_ = $repchar; } } $out = join ("", @q); print "out === $out";
Restructuring the insides of the loop, we can get:
foreach (@q) { if ($_ eq $matchchar) { if (++$count >= $nummatch) { $_ = $repchar; } } }
Now compressing the two if's, we get:
foreach (@q) { if ($_ eq $matchchar && ++$count >= $nummatch) { $_ = $repchar; } }
Now, notice that we are assigning one value to $_ when a certain condition is satisfied, and another (actually leaving its old value) when it's not. So we could use the conditional operator to eliminate the if altogether:
foreach (@q) { $_ = ($_ eq $matchchar && ++$count >= $nummatch)?$repchar:$_; }
And now, notice that we are using the foreach to compute a value based on each element of @q. Ideal use of map!
@q = map { ($_ eq $matchchar && ++$count >= $nummatch)?$repchar:$_ } @q;
And now we don't need to initially asign the result of the split to @q, because all we are doing with it is passing it as argument to map, so we can do:
@q = map { ($_ eq $matchchar && ++$count >= $nummatch)?$repchar:$_ } split(//, $p);
And finally, we can eliminate @q altogether because we can pass the result of the map directly to the join:
$out = join ("", map { ($_ eq $matchchar && ++$count >= $nummatch)?$repchar:$_ } split (//, $p));
Proof that any program can be transformed to a one-liner in Perl :-)

Man that was fun :-)

--ZZamboni

Replies are listed 'Best First'.
Re: Re: Re: Replacing a given character starting with the xth occurence in a string
by sharle (Acolyte) on May 22, 2001 at 08:35 UTC
    This was great! Thanks!

    I spent a huge amount of time trying to figure out how to split on characters, I tried everything except what you used. (I was at work, and so only had the man pages to work from).

    All of your tips were greatly appreciated. I didn't know that foreach automatically assigned $_. Useful knowledge, that.

    I like the result much better than my original, and it was very cool to see how to use map.

    Still Learning, sharle