Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

How to substitute the elements in an array without changing the original array.

by Anonymous Monk
on Dec 01, 2006 at 05:36 UTC ( #587124=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

This node falls below the community's threshold of quality. You may see it by logging in.
  • Comment on How to substitute the elements in an array without changing the original array.

Replies are listed 'Best First'.
Re: How to substitute the elements in an array without changing the original array.
by davido (Cardinal) on Dec 01, 2006 at 05:54 UTC

    I have a box of a dozen doughnuts. I want to eat three of them, and still have a full box with a dozen when I'm done.

    Solution? You need another box. ;)

    In Perl, you need two arrays; one is the original, and one will be the copy, on which you can perform whatever manipulations you wish, without affecting the original.

    my @array = qw/one two three four five/; my @copy = @array; shift @copy; print "Original: @array\n"; print "Copy: @copy\n";

    There are infinite other strategies, but your question is vague enough to make it impossible to focus on which strategy would be optimal.


    Dave

Re: How to substitute the elements in an array without changing the original array.
by ikegami (Patriarch) on Dec 01, 2006 at 06:04 UTC

    You want grep (to remove rows), map (to transform rows) or List::MoreUtils's apply (to transform rows).

    When using grep or map, don't change $_ unless you want to change the original array.

    apply is similar to map, but you can safely modify $_. The downside to using apply is that you're limited to 1:1 transformations (whereas map is extremely flexible).

    use List::MoreUtils qw( apply ); my @orig = qw( Just another Perl hacker ); my @grepped = grep { /^[A-Z]/ } @orig; my @mapped = map { uc } @orig; my @applied = apply { s/[aiueo]//ig } @orig; print("@orig\n"); # Just another Perl hacker print("@grepped\n"); # Just Perl print("@mapped\n"); # JUST ANOTHER PERL HACKER print("@applied\n"); # Jst nthr Prl hckr

    List::MoreUtils can easily be installed if you're using ActivePerl. Just type by ppm install List-MoreUtils at the prompt

Re: How to substitute the elements in an array without changing the original array. - map
by imp (Priest) on Dec 01, 2006 at 05:51 UTC
    See map.
    my @source = (1,2,3,4); my @dest = map { $_ * 2 } @source; print "@source\n"; print "@dest\n"; #Output: #1 2 3 4 #2 4 6 8
    my @source = ('bob', 'joe'); my @dest = map { $_ eq 'bob' ? ucfirst($_) : $_ } @source; print "@source\n"; print "@dest\n"; #Output: #bob joe #Bob joe
      @a=("sedam","medam","kadam","sadam"); for(@b=@a) { s/dam/lam/; } print "@b\n"; print "@a";
Re: How to substitute the elements in an array without changing the original array.
by shotgunefx (Parson) on Dec 01, 2006 at 06:19 UTC
    And to add to these fine comments for future reference, they only really apply to simple scalars (strings, numbers), array references, hash references, etc are a slightly trickier matter.

    You would need to make copies of the data itself and not just the references to the data

    -Lee
    "To be civilized is to deny one's nature."
Re: How to substitute the elements in an array without changing the original array.
by perladdict (Chaplain) on Dec 01, 2006 at 08:43 UTC
    hey, if u r trying to replace the strings by using s///operator,the below code will wok fine.
    #!/usr/bin/perl -w @a=("sedam","medam","kadam","sadam"); for(@b=@a) { s/dam/lam/; } print "@b\n"; print "@a";
Re: How to substitute the elements in an array without changing the original array.
by Firefly258 (Beadle) on Dec 02, 2006 at 00:46 UTC
    I tend to use a few tricks with map and grep to preserve the original array than to seek out and use something different.
    @new = map { ... } @{[ @original ]};
    or even
    @new = grep { local $_ = $_; ... } @original;
    If legibility (management overhead due to fussy boss) is a concern, I then choose to use an idomatic version of the for / do { ... } for loop.
    ... for @new = @original;
    or if you want multiple expressions within the loop..
    do { ...; ... } for @new = @original;


    perl -e '$,=$",$_=(split/\W/,$^X)[y[eval]]]+--$_],print+just,another,split,hack'er

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://587124]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2023-02-09 06:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer not to run the latest version of Perl because:







    Results (44 votes). Check out past polls.

    Notices?