Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I print a Perl two-dimensional array?

Tags:

arrays

perl

I am trying to write a simple Perl script that reads a *.csv, places the rows of the *.csv file in a two-dimensional array, prints an item out of the array, and prints a row of the array.

#!/usr/bin/perl
use strict;
use warnings;

open(CSV, $ARGV[0]) || die("Cannot open the $ARGV[0] file: $!");
my @row;
my @table;

while(<CSV>) {
    @row = split(/\s*,\s*/, $_);
    push(@table, @row);
}
close CSV || die $!;

foreach my $element ( @{ $table[0] } ) {
    print $element, "\n";
}

print "$table[0][1]\n";

When I run this script I receive the following error and nothing prints:

Can't use string ("1") as an ARRAY ref while "strict refs" in use at ./scripts.pl line 16.

I have looked in a number of other forums and am still not sure how to fix this issue. How can fix I this?

like image 881
Matt Pascoe Avatar asked Jun 10 '10 21:06

Matt Pascoe


People also ask

How do I print a 2D array in Perl?

#push(@table, @row); push(@table, \@row); #push a reference to the array into each cell in @table. Then it prints out ok.

How do I print an array in 2D?

Example. public class Print2DArray { public static void main(String[] args) { final int[][] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; for (int i = 0; i < matrix. length; i++) { //this equals to the row in our matrix. for (int j = 0; j < matrix[i].

How do I print a dimensional array?

To print the content of a one-dimensional array, use the Arrays. toString() method. To print the content of a a multi-dimensional array, use the Arrays. deepToString() method.

How do you find a two-dimensional array?

The size of a two dimensional array is equal to the multiplication of number of rows and the number of columns present in the array.


1 Answers

You aren't creating a two-dimensional array (an AoA or "Array of Arrays" in Perl-parlance). This line:

push(@table, @row);

appends the data in @row to @table. You need to push a reference instead, and create a new variable each time through the loop so that you don't push the same reference repeatedly:

my @table;
while(<CSV>) {
    my @row = split(/\s*,\s*/, $_);
    push(@table, \@row);
}

While using split is okay for trivial CSV files, it's woefully inadequate for anything else. Use a module like Text::CSV_XS instead:

use strict;
use warnings;
use Text::CSV_XS;

my $csv  = Text::CSV_XS->new() or die "Can't create CSV parser.\n";
my $file = shift @ARGV         or die "No input file.\n";
open my $fh, '<', $file        or die "Can't read file '$file' [$!]\n";

my @table;
while (my $row = $csv->getline($fh)) {
    push @table, $row;
}
close $fh;

foreach my $row (@table) {
    foreach my $element (@$row) {
        print $element, "\n";
    }
}

print $table[0][1], "\n";
like image 51
Michael Carman Avatar answered Nov 05 '22 20:11

Michael Carman