Reputation: 13
I am trying to transpose an array.
I tried the following code...
#! /usr/bin/perl
use strict;
use warnings;
use autodie;
open my $fh, '<',"op.txt" || die "$!";
open my $wh , '>',"pwl.txt" || die "$!";
select ($wh);
while (my $line = <$fh>) {
my @rows = $line;
my @transposed;
for my $row (@rows) {
for my $column (0 .. $#{$row}) {
push(@{$transposed[$column]}, $row->[$column]);
}
}
for my $new_row (@transposed) {
for my $new_col (@{$new_row}) {
print $new_col, " ";
}
print "\n";
}
}
**********INPUT FILE******
1 2 3
4 5 6
7 8 9
********** EXPECTED OUTPUT FILE *******
1 4 7
2 5 8
3 6 9
******** GENERATED OUTPUT FILE *******
Currently couldn't able print anything. script shows the error "can't use string ("1 4 7") as an array ref while "strict refs" in use
Reference: used the following reference... Transpose in perl however in this reference example, array input lines are declared manually where as i am trying to process a array which is in a text file
could anybody help me where i did mistake?
Many Thanks
Upvotes: 0
Views: 530
Reputation: 126722
Here's a simpler way of doing this. It assumes all the rows are of the same length, and that all the lines in the file contain data -- i.e. there are no blank lines
The name of the input file is expected as a parameter on the command line, and the output is sent to STDOUT so it can be redirected on the command line. For instance
perl transpose.pl op.txt > pwl.txt
use strict;
use warnings 'all';
my @matrix = map [ split ], <>;
print "@$_\n" for @matrix;
print "\n";
my @transpose;
for my $i ( 0 .. $#{ $matrix[0] } ) {
$transpose[$i] = [ map { $_->[$i] } @matrix ]
}
print "@$_\n" for @transpose;
print "\n";
1 2 3
4 5 6
7 8 9
1 4 7
2 5 8
3 6 9
Upvotes: 0
Reputation: 13
adding my @row =map [ split], $line
to my initial code is helping to print the data to pwl.txt.
however its not printing side by side.. instead it is printing to new line. I guess because of this Mr.Borodin didn't include matrix in side while loop!
1
2
3
4
5
6
7
8
9
Upvotes: 0
Reputation: 33601
You did have to split input line as @dland suggested. But, there were a few other issues.
Here's the corrected code [please pardon the gratuitous style cleanup]:
#! /usr/bin/perl
use strict;
use warnings;
use autodie;
open my $fh, '<',"op.txt" || die "$!";
open my $wh , '>',"pwl.txt" || die "$!";
my @rows;
while (my $line = <$fh>) {
my @line = split(" ",$line);
push(@rows,\@line);
}
close($fh);
my @transposed;
for my $row (@rows) {
push(@transposed,[]);
}
my $rowidx = -1;
for my $rowptr (@rows) {
++$rowidx;
my $colidx = -1;
for my $rowval (@$rowptr) {
++$colidx;
###printf("R=%d C=%d\n",$rowidx,$colidx);
my $colptr = $transposed[$colidx];
$colptr->[$rowidx] = $rowval;
}
}
for my $new_row (@transposed) {
for my $new_col (@$new_row) {
print $wh $new_col, " ";
}
print $wh "\n";
}
close($wh);
Note: It's slightly harder to transpose a non-square matrix. The above code may need to be extended a bit for that.
Upvotes: 1
Reputation: 4419
You're trying to shove a scalar into an array:
my @row = $line;
I think what you really want is to split on spaces:
my @row = split / /, $line;
Upvotes: 0