How to pass around an Array of Arrays (or Array Refs)

J

jerrykrinock

I need to pass an array of arrays from a function, but I can't make an
array of arrays work. Actually, I've got better results making an
array of array references. Here's what I've done:

#!/usr/bin/perl

my @array ;
my @row ;
@row = ('a00', 'a01') ;
push (@array, \@row) ;
@row = ('a10', 'a11') ;
push (@array, \@row) ;
@row = ('a20', 'a21') ;
push (@array, \@row) ;

# In real life I will return @array to the caller, but the
# problem can be demonstrated without doing that...

my $nRows = @array ;
foreach my $array_ref (@array) {
# $array_ref is a reference to an array (row)
# Dereference it.
my @row = @$array_ref ;
# Print each element (column) separated by spaces
foreach my $element (@row) {
print "$element ";
}
# Next row, new line
print "\n" ;
}

My expected result is:

a00 a01
a10 a11
a20 a21

but the actual result is:

a20 a21
a20 a21
a20 a21

What am I doing wrong?

Thanks,

Jerry Krinock
 
J

Joost Diepenmaat

I need to pass an array of arrays from a function, but I can't make an
array of arrays work. Actually, I've got better results making an
array of array references. Here's what I've done:

#!/usr/bin/perl

my @array ;
my @row ;
@row = ('a00', 'a01') ;
push (@array, \@row) ;
@row = ('a10', 'a11') ;
push (@array, \@row) ;
@row = ('a20', 'a21') ;
push (@array, \@row) ;

What am I doing wrong?

You're reusing the same array for each row; each row is a reference to
the same array (@row), which means you end up with each row containing
the values you last assigned to @row.

You want something like:

my @array ;
my @row ;
@row = ('a00', 'a01') ;
push (@array, [ @row ]); # [ @row ] creates a reference to a new array
# with copies of the values in @row.
@row = ('a10', 'a11') ;
push (@array, [ @row ]);
@row = ('a20', 'a21') ;
push (@array, [ @row ]);


or less ugly:

my @array = ( [ 'a00', 'a01' ],
[ 'a10', 'a11' ] );

push @array, ['a20','a21'];
 
A

A. Sinan Unur

(e-mail address removed) wrote in (e-mail address removed):
I need to pass an array of arrays from a function, but I can't make an
array of arrays work. Actually, I've got better results making an
array of array references. Here's what I've done:

#!/usr/bin/perl

my @array ;
my @row ;
@row = ('a00', 'a01') ;
push (@array, \@row) ;
@row = ('a10', 'a11') ;
push (@array, \@row) ;
@row = ('a20', 'a21') ;
push (@array, \@row) ;

Would it be easier to understand if I changed the above to:

my $array_ref = [
[ qw( a00 a01 ) ],
[ qw( a10 a11 ) ],
[ qw( a20 a21 ) ],
];

In what you wrote above, you are pushing the reference to the same array
(@row) and you keep overwriting the contents of @row. So, now you have
three references pointing to the exact same array.

#!/usr/bin/perl

use strict;
use warnings;

my @array;

my @row = ('a00', 'a01') ;
push (@array, \@row) ;
@row = ('a10', 'a11') ;
push (@array, \@row) ;
@row = ('a20', 'a21') ;
push (@array, \@row) ;

print "$_\n" for @array;

__END__

E:\Home\asu1\Src\Test> s1
ARRAY(0x182a2fc)
ARRAY(0x182a2fc)
ARRAY(0x182a2fc)


--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
J

Jürgen Exner

I need to pass an array of arrays from a function, but I can't make an
array of arrays work.

That's because you can't. The argument list as well as the return value
of a function is a flat sequence of scalars. It is impossible to pass an
array of arrays (or list of arrays for that matter).
Actually, I've got better results making an
array of array references. Here's what I've done:

And that's exactly what you should be doing.

jue
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top