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

Hi monks,

Just a quickie, if I read through a file line-by-line
putting it into an array using a while loop, and the data is like this:

ABC
DBC
ECC


I would like $array[0] to be ADE and $array[1] to be BBC etc.
Is there a way of appending to array values like this ?
I know how to use push to add to an array, but thats not what I want to do :(
I use split to put the line into $array[0], array[1] etc.
cheers

Edit: Added <code> tags. larsen

Replies are listed 'Best First'.
Re: append array
by Abigail-II (Bishop) on Jun 12, 2002 at 13:37 UTC
    There isn't a trivial way to do this. One way is:
    #!/usr/bin/perl use strict; use warnings 'all'; my @arr1 = map {[split //]} <DATA>; my @arr2 = map {my $n = $_; join "" => map {$_ -> [$n]} @arr1} 0 .. @{$arr1 [0]} - 2; print "$_\n" for @arr2; __DATA__ ABC DBC ECC FFF
    This will print
    ADEF
    BBCF
    CCCF
    

    Abigail

Re: append array
by demerphq (Chancellor) on Jun 12, 2002 at 13:33 UTC
    Some people smell homework... Me ive got a cold so I cant smell anything....

    use strict; use warnings; my @list=map{chomp;$_}<DATA>; my @output; foreach my $line (@list) { foreach my $ofs (0..length($line)-1) { $output[$ofs].=substr($line,$ofs,1); } } print join ("\n",@output),"\n"; __DATA__ ABC DEF GHI JKL MNO PQR STU
    Outputs

    ADGJMPS
    BEHKNQT
    CFILORU
    

    I hope I get a good mark ;-)

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.

Re: append array
by vladb (Vicar) on Jun 12, 2002 at 13:30 UTC
    Give this a shot:
    use Data::Dumper; my @array; # read from the file handle line by line while(<DATA>) { chomp; # split each line by ',' and save # corresponding records into the @recs array my @recs = split /\,/; # loop through the records array.. for (my $i; $i < @recs; $i++) { # and save I-th record in array # array[I]. Use @{..} to let push() know # that array[I] is also an array. push @{$array[$i]}, $recs[$i]; } } print Dumper(\@array); __DATA__ A,B,C D,B,C E,C,C
    The ouptut I get is
    $VAR1 = [ [ 'A', 'D', 'E' ], [ 'B', 'B', 'C' ], [ 'C', 'C', 'C' ] ];
    I believe this is what you were looking for?

    _____________________
    open(I,$0);<I>;$~=$/;$/='~';$_=<I>;($/)=/(.)$~/;s/[$~~]//g;/(v)/;$-=$-[0];s;\Q$/\E;$~;g;($/,$^)=/^(.)(.)/;
    #%  xxxxxx   xx-+  xx    xxx xx  xx       xx  xx   xxx   xxxxx+ xx  xx xxxx xxxxx  ......+
    #x xxxxvxxx xx  xx xv   xxxx x+ %+  ===== xx  xx  xx xx  x+  =x xx xx  xx   xx xx ...+
    #x xx xx xx xx  xx xx  xx xx xxx+         xxxxxx xx   +x xx     xx+x-  xxxx xxxx ........+
    #% xx xx xx xx  xx xx xx  x+ xx xx  =+=== xx  xx xxxx-xx xx  =x +x xx  xx   xx xx ...+
    #% xx xx xx  -+x+  xxx+   xx xx  xx       xx  xx x+   xx xxx+xx xx  xx xxxx xx  xx ....+~
    for(split/$~/){s,[ $/],,g;/(.)$/;$l=$-[0];/(.)/||next;$_=chr$-+$l;$".=($1=~/$^/)?" \u$_":$_;}print$";
    
Re: append array
by atcroft (Abbot) on Jun 12, 2002 at 13:32 UTC

    Since this smells of homework, I'll be brief. You'll need a split and a loop, and to do an append, if you want the first element to contain everything in the first columm, etc. That much should lead you to the answer, with some thought.

    Failing that, I am adding an additional hint from a CB discussion with broquaint, but try this for yourself first-you will gain more from the thought involved than you may realize.

    split the string char for char, then append it to the array with its position.... as long as all strings are the same length.... hrm...

Re: append array
by marvell (Pilgrim) on Jun 12, 2002 at 13:34 UTC

    How about something along the lines of:

    #!/usr/bin/perl use Data::Dumper; while (<DATA>) { my $i=0; for $c (/./g) { push (@{$array[$i++]}, $c); } } print Dumper(\@array); __DATA__ ABC DBC ECC

    --
    Steve Marvell

Re: append array
by Sifmole (Chaplain) on Jun 12, 2002 at 14:34 UTC
    Just for kicks:
    #!/usr/local/bin/perl use Data::Dumper; map{(/\n/)?$i=0*$j++:$r[$i++][$j]=$_;}split // while(<DATA>); print Dumper(\@r); __DATA__ ABC DBC ECC
    Update:
    I know map in void context, hard to read, ugly, not strict, bad. I just felt like golfing it.

    Update 2:
    map{(/\n/)?$i=0*$j++:$r[$i++][$j]=$_;}split//for<DATA>;