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

Hi Perlmonks,

I am trying to get the transpose of a .csv file. When I executed the code below, I get the error message "Can't use a string (" ") as an ARRAY ref while "strict refs" in use at line 17". I am not sure how to solve this problem.

#!/usr/bin/perl -w use strict; use warnings; use Text::CSV_XS; open(my $FILE1, '<', "inputfile.csv") or die "cannot open file1 $!\n"; open(my $FILE2, '>', "outputfile.csv") or die "cannot open file2 $!\n" +; my $csv =Text::CSV_XS-> new({binary=> 1, eol=> $/, sep_char=> "\t", al +ways_quote=>1}); my @tfields; while(my $row=$csv->getline($FILE1)) { my @fields=@$row; for my $y (0..(@fields-1)) { for my $x (0..@{$fields[$y]}-1) { $tfields[$x][$y] = $fields[$y][$x]; $csv->print($FILE2,\@tfields); } } }

Replies are listed 'Best First'.
Re: Transpose of an array
by ikegami (Patriarch) on Oct 13, 2011 at 19:17 UTC

    $fields[$y] is value of one of the fields of the current rec/line, but you're trying to use it as an array (@{$fields[$y]}).

    Something is very wrong with your approach since you're printing before reading the entire file, but you don't have the information you need for the first row before you read the entire file.

    Solution:

    my @transposed; while (my $row = $csv->getline($FILE1)) { for (0..$#$row) { push @{ $transposed[$_] }, $row->[$_]; } } $csv->print($FILE2, $_) for @transposed;
      Hi,

      Thanks for the code. It worked. In fact, yesterday, I wrote a similar type of code (which worked fine-pasted below). But, I was trying to get it done through two dimensional arrays.

      my $tfields; while (my $row=$csv->getline($FILE1)) { for (my $i = 0; $i < @$row; $i++){ push (@{$tfields -> [$i]}, $row ->[$i]); } } foreach my $row (@$tfields) { $csv->print ($FILE2, $row); }
        huh? It does build a 2d array.
Re: Transpose of an array
by Eliya (Vicar) on Oct 13, 2011 at 19:13 UTC

    You can't transpose a two-dimensional array ($fields[][]) you haven't set up yet.

    $csv->getline() reads one line from the CSV file, the column values of which you have in @fields. I.e. $fields[$y] in line 17 doesn't hold an array ref, so you can't dereference it, which is why Perl complains...

    The solution would be (if the CSV data fits into memory), to read all data into memory, then transpose the resulting (two-dimensional) array, and finally write it out.