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

Hi, I have an array like this:
@array $array[0]="0\n1\n2\n3\n" $array[1]="4\n5\n6\n" $array[2]="7\n8\n" $array[3]="9\n"
So if I print @array the result is:
0 1 2 3 4 5 6 7 8 9
I hope to have a result like this:
0 1"\t"4" 2"\t"5"\t"7 3"\t"6"\t"8"\t"9
can someone help me?

Replies are listed 'Best First'.
Re: array in different columns
by Corion (Patriarch) on Nov 23, 2016 at 09:46 UTC

    You don't show the code you've already written so I'm going to assume that this is homework.

    Have you thought about whether the problem would be easier if your array contained different values?

    How would you approach the problem if your array contained ten elements like the following:

    @array = (0..9);

      No, this isn't a homework but the final part of a script.

      The result of my script is an array like this:

      @array=(--, 0.0175, 0.0483, 0.0507, --, 0.0471, 0.0483, --, 0.0287, --)

      the length of the array can be differ; depend by the input file

      so if I print this array I obtain:
      print @array; -- 0.0175 0.0483 0.0507 -- 0.0471 0.0483 -- 0.0287 --
      Instead I hope to have:
      0 0.0175"\t"0 0.0483"\t"0.0471"\t"0 0.0507"\t"0.0483"\t"0.0287"\t"0
      So I tried to insert the array inside a variable and then split it into array
      my $fileAverage = join "", @array; $fileAverage =~ s/--\n/--0\n/g; my (@matrix) = split('--', $fileAverage); foreach my $lane (@matrix) {print "\t$lane"; }
      but I obtain:
      "\t"0 0.0175 0.0483 0.0507 "\t"0 0.0471 0.0483 "\t"0 0.0287 "\t"0

        Maybe you want to think of it in a different way, by looking at how to divide the array across columns. If you build your columns and then print every row of your column, you should get your result. I'm going to first show you how to do it for a fixed number of columns and then how to expand that to an arbitrary number of columns:

        my @column1; my @column2; my @column3; my @column4; while( @array and $array[0] ne '--') { push @column1, shift @array; }; shift @array; while( @array and $array[0] ne '--') { push @column2, shift @array; }; shift @array; while( @array and $array[0] ne '--') { push @column3, shift @array; }; shift @array; while( @array and $array[0] ne '--') { push @column4, shift @array; }; shift @array; for my $row (1..3) { print join "\t", $column1[$row], $column2[$row],$column3[$row],$co +lumn4[$row]; print "\n"; };

        Now, that only works for four columns. To make it work with any number of columns, we need to move away from the named column arrays and store all column arrays in another array ("AoA"):

        my @column; my $curr_column = 0; my $rows = 0; while( @array and ) { if( $array[0] ne '--' ) { $column[ $curr_column ] ||= []; # a new column push @{ $column[ $curr_column ] }, shift @array; if( $rows < $#{ $column[ $curr_column ] } ) { $rows = $#{ $column[ $curr_column ] }; }; } else { $index++; shift @array; }; }; for my $row (0..$rows) { print join "\t", map { $_->[ $row ] } @column; print "\n"; };

        I also tried with this code

        my $count3="-1"; foreach my $lane (@array) { if ($lane eq "--\n"){$count3++;print "\t" x $count3 . "0\n";} else {print "\t" x $count3 . "$lane"} }
        but I obtained:
        0 0.0175 0.0483 0.0507 "\t" 0 "\t" 0.0471 "\t" 0.0483 "\t\t" 0 "\t\t" 0.0287 "\t\t\t" 0
Re: array in different columns
by Ratazong (Monsignor) on Nov 23, 2016 at 11:52 UTC

    Do you have the freedom of adapting your data-structure? Here an array of arrays looks much more suitable than the one-dimensional array of values seperated by \n that you use.

    HTH, Rata

Re: array in different columns
by tybalt89 (Monsignor) on Nov 23, 2016 at 14:20 UTC
    #!/usr/bin/perl # http://perlmonks.org/?node_id=1176395 use strict; use warnings; my @array; $array[0]="0\n1\n2\n3\n"; $array[1]="4\n5\n6\n"; $array[2]="7\n8\n"; $array[3]="9\n"; my @result; for my $start (0..$#array) { my $to = $start; $result[$to++] .= "\t" x !!$start . $1 while $array[$start] =~ /(.+) +\n/g; } print "$_\n" for @result;

    outputs:

    0 1 4 2 5 7 3 6 8 9
Re: array in different columns
by Marshall (Canon) on Nov 23, 2016 at 16:27 UTC
    Here is another formulation for you using data from your OP. This makes a 2D array and then prints it. I tried to be straight-forward. Hope this is understandable to you. Pay attention to the code that prints each row of the 2D array. This type of thing occurs often.
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @array; $array[0]="0\n1\n2\n3\n"; $array[1]="4\n5\n6\n"; $array[2]="7\n8\n"; $array[3]="9\n"; my @twod_array; my $i_col=0; foreach my $col (@array) { my $i_row = $i_col; #we go down a diagonal to right my @row_stuff = split (' ',$col); foreach my $ele (@row_stuff) { $twod_array[$i_row++][$i_col] = $ele; } $i_col++; } foreach my $row_ref (@twod_array) { my $line = join ("\t", @$row_ref); print "$line\n"; } =prints: 0 1 4 2 5 7 3 6 8 9 =cut
    Update: I thought I'd comment on this: split (' ',$col). This does not mean "split on the space character". This is a special case coded into Perl. This means "split on any sequence of white space characters". There are five: space,line feed,carriage return,tab,form feed. There is a difference in how leading white space is handled between that split and split (/\s+/,$col) which doesn't matter here and gets us a bit far afield.