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

What is the best way to get rid of the space in array between items?

@array1
abc abc abc abc abc
abc abc abc2 abc3 abc4 abc5
abc abc abc1 abc2

so that @array2 would look like
abcabcabcabcabc
abcabcabc2abc3abc4abc5
abcabcabc1abc2

I thought below could do it, but cleary can't
foreach my $element (@fields) { $element =~ s/\s+//g; $element .= $element; }

Replies are listed 'Best First'.
Re: array with s///g command
by GrandFather (Saint) on Jul 29, 2007 at 23:29 UTC
    use strict; use warnings; my @array1 = ( 'abc abc abc abc abc', 'abc abc abc2 abc3 abc4 abc5', 'abc abc abc1 abc2', ); my @array2; for (@array1) { push @array2, $_; $array2[-1] =~ s/\s+//g; } print "@array2";

    Prints:

    abcabcabcabcabc abcabcabc2abc3abc4abc5 abcabcabc1abc2

    DWIM is Perl's answer to Gödel
Re: array with s///g command
by Trimbach (Curate) on Jul 29, 2007 at 23:53 UTC
    Or, if you want to be brief...
    # assuming @array1 contains the values to change. my @array2 = @array1; @array2 = map { s/\s//g; $_ } @array2; print @array2;

    Gary Blackburn
    Trained Killer

      Slightly cleaner:
      my @array2 = @array1; s/\s+//g for (@array2);
      Or in a single statement:
      my @array2 = map {(my $x = $_) =~ s/\s+//g; $x} @array1;
      The main concern you must have when dealing with map and a regex is not destructing the original array unless you truly intend to. $_ is an alias to each element of the source array, so any modification of it modifies the original array. To avoid this we assign to a temporary lexical in the above map block. And then finally make sure to return the actual variable and not a count of the number of substitutions.

      Personally, I'd probably just stick with your original code, as I kind of doubt that you truly need a second array with these crunched values. Instead simply add the "crunching" as part of the loop for whatever other processing that you intend to be doing. Whatever that may be.

      - Miller
        thanks guys, it's working. I still dont' understand map too well(along with many other things).. can someone show me a URL that has map tutorial better than http://perldoc.perl.org/functions/map.html ?? Their explanation on how to mix it in with other does not make much sense to me.
        You can simply join the statements
        my @array2 = @array1; s/\s+//g for (@array2);
        into one:
        tr/ //d for my @array2 = @array1;
        The tr/// here only treats blanks instead of general white space, but that's easily changed if necessary.

        Anno

      I like brief too ... why not simply:?
      my @array2 = map { s/\s+//g; $_ } @array1;

      Update  Whoops, now I see ... it's because you'd be changing the original array.  Still, I like the brevity of something like:

      my @array2 = map { (my $x = $_) =~ s/\s+//g; $x } @array1;

      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

        Because that mangles @array1 - $_ is aliased to each element from @array1 and the substitution clobbers the original value


        DWIM is Perl's answer to Gödel
      tr/ //d for @array2;

      will probably be a tad faster, in that it transliterates, and avoid using a code block.

      • another intruder with the mooring in the heart of the Perl

Re: array with s///g command
by ysth (Canon) on Jul 29, 2007 at 23:35 UTC
    Without the .= statement, that should do the trick, assuming your
    @array1 abc abc abc abc abc abc abc abc2 abc3 abc4 abc5 abc abc abc1 abc2
    means
    @array1 = ( 'abc abc abc abc abc', 'abc abc abc2 abc3 abc4 abc5', 'abc abc abc1 abc2' );
    If it's not working, you need to be more explicit with us (and yourself?) about what's in your array, for instance, by showing the output of
    use Data::Dumper; $Data::Dumper::Useqq=1; print Dumper \@array;

      That will update @array1. OP implied that @array2 should have the updated strings. Of course it may be that OP intended the two arrays to actually represent the contents of an unspecified array at two different time, in which case:

      s/\s+//g for @fields;

      may be what OP is looking for.

      I find it a little tricky to read some OP's minds at times. ;)


      DWIM is Perl's answer to Gödel