Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

access a 2D array column by column

7 views
Skip to first unread message

ela

unread,
Nov 24, 2011, 10:27:24 PM11/24/11
to
To access a spreadsheet file column by column, I use the 2D array @AoA to
store the contents. However, I don't know how to state in the for loop
because common perl tutorials assume access row by row. What should I
replace $#AoA with?


use warnings;

my ($rankfile) = @ARGV;
open (FP,$rankfile);
my @cells = (); my @AoA = ();
while ($line=<FP>) { chomp $line; @cells = split /\t/, $line;
push @AoA, [ @cells ];
}

%trials = ();
%sTrials = ();
for $i ( 0 .. $#AoA ) {
for $ik ( 0 .. $#{ $AoA[$i] } ) {
$trials{$ik} = $AoA[$i][$ik];
print $ik, "\t", $trials{$ik} , "\t", $AoA[$i][$ik]; <STDIN>;
}
}


Jürgen Exner

unread,
Nov 24, 2011, 11:36:57 PM11/24/11
to
"ela" <e...@yantai.org> wrote:
>To access a spreadsheet file column by column, I use the 2D array @AoA to
>store the contents. However, I don't know how to state in the for loop
>because common perl tutorials assume access row by row. What should I
>replace $#AoA with?

Do you know what $#AoA is? Why do you think that picking some other
number would change the logic of your algorithm from columns of rows to
rows of columns?

>use warnings;
>
>my ($rankfile) = @ARGV;
>open (FP,$rankfile);
>my @cells = (); my @AoA = ();
>while ($line=<FP>) { chomp $line; @cells = split /\t/, $line;
> push @AoA, [ @cells ];
>}
>
>%trials = ();
>%sTrials = ();
>for $i ( 0 .. $#AoA ) {
> for $ik ( 0 .. $#{ $AoA[$i] } ) {
> $trials{$ik} = $AoA[$i][$ik];
> print $ik, "\t", $trials{$ik} , "\t", $AoA[$i][$ik]; <STDIN>;
> }
>}

You need to change your algorithm to have the outer loop iterate over
the columns and the inner loop over the rows.

jue

ela

unread,
Nov 24, 2011, 11:48:37 PM11/24/11
to

"Jürgen Exner" <jurg...@hotmail.com> wrote in message
news:lk6uc7lcbav40d0th...@4ax.com...
> "ela" <e...@yantai.org> wrote:
>>To access a spreadsheet file column by column, I use the 2D array @AoA to
>>store the contents. However, I don't know how to state in the for loop
>>because common perl tutorials assume access row by row. What should I
>>replace $#AoA with?
>
> Do you know what $#AoA is? Why do you think that picking some other
> number would change the logic of your algorithm from columns of rows to
> rows of columns?

The problem is I don' t know what the last index for a 2D array refers to...

> You need to change your algorithm to have the outer loop iterate over
> the columns and the inner loop over the rows.

Yes. I should iterate over the columns and then rows. That's why I first
store the file content into a 2D array. Say, if I have something like:

array of size 3 by 2

15 6
3 9
7 18

then if I have to access as 15, 3, 7 and then 6,9,18 I should move the first
index, e.g. arr[0][0], arr[1][0], and arr[2][0]; then
arr[0][1], arr[1][1] and arr[2][1]


Jürgen Exner

unread,
Nov 25, 2011, 12:04:05 AM11/25/11
to
"ela" <e...@yantai.org> wrote:
>
>"Jürgen Exner" <jurg...@hotmail.com> wrote in message
>news:lk6uc7lcbav40d0th...@4ax.com...
>> "ela" <e...@yantai.org> wrote:
>>>To access a spreadsheet file column by column, I use the 2D array @AoA to
>>>store the contents. However, I don't know how to state in the for loop
>>>because common perl tutorials assume access row by row. What should I
>>>replace $#AoA with?
>>
>> Do you know what $#AoA is? Why do you think that picking some other
>> number would change the logic of your algorithm from columns of rows to
>> rows of columns?
>
>The problem is I don' t know what the last index for a 2D array refers to...

In Perl there is no such thing as a 2D array. As AoA indicates you got
an _A_rray _o_f (references to) _A_rrays.

>> You need to change your algorithm to have the outer loop iterate over
>> the columns and the inner loop over the rows.
>
>Yes. I should iterate over the columns and then rows. That's why I first
>store the file content into a 2D array. Say, if I have something like:
>
> array of size 3 by 2
>
>15 6
>3 9
>7 18
>
>then if I have to access as 15, 3, 7 and then 6,9,18 I should move the first
>index, e.g. arr[0][0], arr[1][0], and arr[2][0]; then
>arr[0][1], arr[1][1] and arr[2][1]

So, where is the problem?

for $col in (0..1) {
for $row in (0..2) {
print $arr[$row][$col]
}
}

jue

Tad McClellan

unread,
Nov 25, 2011, 12:16:27 AM11/25/11
to
ela <e...@yantai.org> wrote:
>
> use warnings;


You should enable strict on every Perl program:

use strict;


> my ($rankfile) = @ARGV;
> open (FP,$rankfile);


You should always, yes *always*, check the return value from open().

You should use the 3-argument form of open().

You should use a lexical filehandle.

open my $FP, '<', $rankfile or die "could not open '$rankfile' $!";


> my @cells = (); my @AoA = ();


You should declare variables in the smallest possible scope.

Since you do not use @cells outside of the while loop, you should
scope @cells to the while loop's block rather than scoping it
to the whole file like that.


> while ($line=<FP>) { chomp $line; @cells = split /\t/, $line;

while (my $line = <$FP>) {
chomp $line;
my @cells = split /\t/, $line;


> push @AoA, [ @cells ];


Now that @cells is properly scoped, you can take a reference to
it directly rather than having to copy it to an anonymous array:

push @AoA, \@cells;


> }


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
The above message is a Usenet post.
I don't recall having given anyone permission to use it on a Web site.

Justin C

unread,
Nov 25, 2011, 4:55:38 AM11/25/11
to
On 2011-11-25, ela <e...@yantai.org> wrote:
> To access a spreadsheet file column by column, I use the 2D array @AoA to
> store the contents. However, I don't know how to state in the for loop
> because common perl tutorials assume access row by row. What should I
> replace $#AoA with?


This spreadsheet you have, if it's Excel then Spreadsheet::ParseExcel is
useful:


#!/usr/bin/perl

use warnings;
use strict;

use Spreadsheet::ParseExcel;

my $parser = Spreadsheet::ParseExcel->new();
my $wb = $parser->parse($ENV{HOME} . '/some.xls');

die unless defined $wb;

for my $ws ( $wb->worksheets() ) {
my ($row_min, $row_max) = $ws->row_range();
my ($col_min, $col_max) = $ws->col_range();

for my $col ($col_min .. $col_max) {
for my $row ($row_min .. $row_max) {
my $cell = $ws->get_cell($row, $col);
print $cell->value(), "\n";
}
}
}

__END__

But please read and understand the comments others have posted.


Justin.

--
Justin C, by the sea.

John W. Krahn

unread,
Nov 25, 2011, 5:34:27 AM11/25/11
to
Tad McClellan wrote:
> ela<e...@yantai.org> wrote:
>>
> Since you do not use @cells outside of the while loop, you should
> scope @cells to the while loop's block rather than scoping it
> to the whole file like that.
>
>
>> while ($line=<FP>) { chomp $line; @cells = split /\t/, $line;
>
> while (my $line =<$FP>) {
> chomp $line;
> my @cells = split /\t/, $line;
>
>
>> push @AoA, [ @cells ];
>
>
> Now that @cells is properly scoped, you can take a reference to
> it directly rather than having to copy it to an anonymous array:
>
> push @AoA, \@cells;

Or just copy the list directly:

while (my $line = <$FP>) {
chomp $line;
push @AoA, [ split /\t/, $line ];



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

Willem

unread,
Nov 25, 2011, 8:24:31 AM11/25/11
to
John W. Krahn wrote:
) Or just copy the list directly:
)
) while (my $line = <$FP>) {
) chomp $line;
) push @AoA, [ split /\t/, $line ];

Or just do it all at once:

my @AoA = map { chomp; [ split /\t/ ] } <$FP>;

Anyone want to go for an eagle?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Tad McClellan

unread,
Nov 25, 2011, 10:41:26 AM11/25/11
to
Justin C <justi...@purestblue.com> wrote:

> But please read and understand


That is extremely unlikely. :-(


> the comments others have posted.


ela

unread,
Nov 28, 2011, 6:39:34 AM11/28/11
to

"Tad McClellan" <ta...@seesig.invalid> wrote in message
news:slrnjcvds6...@tadbox.sbcglobal.net...
> Justin C <justi...@purestblue.com> wrote:
>
>> But please read and understand
>
>
> That is extremely unlikely. :-(
>
>> the comments others have posted.

Trying hard to follow the etiquette. Sometimes when a program is used only
once I somehow become lazy and don't follow strictly... sorry again for
making you disappointed but I always remember when I become rich, this group
should be the first to which I should donate.


Tad McClellan

unread,
Nov 28, 2011, 9:39:37 AM11/28/11
to
ela <e...@yantai.org> wrote:

> Trying hard to follow the etiquette.


Bullshit.


> Sometimes when a program is used only
> once I somehow become lazy and don't follow strictly...

That is OK when you are the only person to see your program,
but once you decide to ask others to spend their time on it too,
it is courteous to go back and remove your "laziness" before posting.

You are the most inconsiderate poster I can remember ever
seeing post here.



"lazy" usually means that you want to do less work, right?

You are not being "lazy" (ie. saving time), you are
being "foolish" (ie. wasting time).


"use strict" will save you time by finding bugs for you.

Using "use strict" is being lazy.


Checking the return value from open() will save you time by
finding bugs for you.

Checking the return value from open() is being lazy.


Proper scoping of variables will save you time by finding bugs for you.

Proper scoping of variables is being lazy.



Start being truly lazy!
0 new messages