Re: how could I use map here?
by Cody Pendant (Prior) on Feb 06, 2003 at 21:37 UTC
|
Call me Mister Obvious, but this works too:
@array2 = @array1;
s/^CHOP_ME_OFF_// for @array2;
--
Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.
M-J D | [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
Re: how could I use map here?
by dws (Chancellor) on Feb 06, 2003 at 20:42 UTC
|
@my_array_2 = map { s/^CHOP_ME_OFF_//g } @my_array;
But this won't work. It gives you an array full of integers, and it modifies the contents of @my_array.
In this case, it's better to use substr.
@my_array_2 = map {
/^CHOP_ME_OFF_/ ?
substr($_, length("CHOP_ME_OFF_")) : $_
} @my_array;
Update: On reflection, might be better off localizing $_
@my_array_2 = map { local $_ = $_; s/^CHOP_ME_OFF_//; $_ } @my_array;
| [reply] [d/l] [select] |
|
|
Re your last solution: what do you gain by localizing $_? Or, equivalently, what is the difference between
@my_array_2 = map { local $_ = $_; s/^CHOP_ME_OFF_//; $_ } @my_array;
and @my_array_2 = map {s/^CHOP_ME_OFF_//; $_ } @my_array;
I've used the latter version often and it seemed to work perfectly fine...
pike
Update:OK, to be honest what I really used was @my_array = map {s/^CHOP_ME_OFF_//; $_ } @my_array;
i. e. I did the replacements in-place, which explains why I never noticed the effect pointed out by adrianh++. | [reply] [d/l] [select] |
|
|
my @x = qw(foo bar CHOP_ME_OFF_foo);
my @y = @x;
my @copies = map { local $_ = $_; s/^CHOP_ME_OFF_//; $_ } @x;
my @changes = map {s/^CHOP_ME_OFF_//; $_ } @y;
print "x @x\ny @y\ncopies @copies\nchanges @changes\n";
| [reply] [d/l] [select] |
|
|
|
|
adrianh++
It's often (always?) a good practice to localize $_ whenever you need to use it, like any other global variable: it could be accessed by your program, or used by modules (File::Find is one of them AFAIK) and it's not fair to mess up with it.
With localizing it you have a better protection: if something elsewhere in your code relied on $_'s value you won't be messing with it.
Ciao! --bronto
The very nature of Perl to be like natural language--inconsistant and full of dwim and special cases--makes it impossible to know it all without simply memorizing the documentation (which is not complete or totally correct anyway).
--John M. Dlugosz
| [reply] [d/l] [select] |
Re: how could I use map here?
by thelenm (Vicar) on Feb 06, 2003 at 20:43 UTC
|
Are you trying to build up a new array of strings with "CHOP_ME_OFF_" removed? First of all, I'm guessing you want to change $value = s/^CHOP_ME_OFF_//g to $value =~ s/^CHOP_ME_OFF_// (using =~ instead of =, and no /g necessary, since it can only match once).
Note: if you do that, then the actual values in @my_array will be modified, since $value is an alias for each one. In that case, you don't need @my_array_2 at all because @my_array will contain the modified values. You might write the code like this:
s/^CHOP_ME_OFF_// for @my_array;
If you don't want to modify the original array, then localize $_ or use a temporary variable in your map, maybe like this:
@my_array_2 = map {local $_=$_; s/^CHOP_ME_OFF_//; $_} @my_array;
-- Mike
--
just,my${.02} | [reply] [d/l] [select] |
Re: how could I use map here?
by grantm (Parson) on Feb 06, 2003 at 20:50 UTC
|
You're almost there, map expects a code block followed by a list eg:
@my_array_2 = map { s/^CHOP_ME_OFF_//g } @my_array;
map will create a new list then execute the code block for each element in the original list and add the return value of the block to the new list.
The trap to watch out for is that s/// returns a count of the number of substitutions performed (or undef if nothing matched). It does not return the contents of the string after the substitution. So the real answer is:
@my_array_2 = map { s/^CHOP_ME_OFF_//g; $_ } @my_array;
Update: Oops, I forgot about the other trap (modifiying the original array) but you already go that from the other answers.
| [reply] [d/l] [select] |
Re: how could I use map here?
by BrowserUk (Patriarch) on Feb 06, 2003 at 21:11 UTC
|
@array2 = map{ /^(?:chop_me_off)?(.*)$/; $1 } @array;
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead. | [reply] [d/l] |
|
|
or even simpler:
@array2 = map /^(?:chop_me_off)?(.*)/, @array2;
m// in list context returns a list of $1, $2, ...
-- Hofmator
| [reply] [d/l] |
|
|
I stay away from using the above technique using .* as a "get everything" pattern. That is mostly because the /s is almost always forgotten. I tend to forget it less nowadays, but even though I manically think about it when I read other's code I sometimes miss it in my own code.
In your code above it leads to an undef entry for every value that has a newline somewhere after "chop_me_off" and before the last char in the string. And then again we have the max limit for quantifiers. See perl -Mre=debug -wle '"a" =~ /a*/'.
ihb
| [reply] [d/l] [select] |
Re: how could I use map here?
by J9 (Beadle) on Feb 06, 2003 at 20:40 UTC
|
Forgive me if I am totally wrong but I think you need to swap the action you want to perform wround with your array. Something like this.
@my_array_2 = map( s/^CHOP_ME_OFF_//g , @my_array );Very untested. | [reply] [d/l] |