Help with Arrays of Arrays
Author Message
Help with Arrays of Arrays

I have a file that looks something like this

a:1
a:2
a:3
b:1
b:2
c:1
c:2

etc.

What I what to produce is the following

a:
1
2
3
b:
1
2
c:
1
2

What I have so far gets me the separate indices ( a, b ,c) and a list
associated with each one. How do I create an associative array so
that I can index the list?

Currently I have the following:

\$flag="start";
while(<DEPT>){
chop;
(\$prev, \$item) = split(/:/, \$_);
if (\$prev ne \$flag) {

\$flag = \$prev;
} else {

}

Quote:
}

Any And All help appreciaated.
Thanks in Advance and please don't condemn the programming style too much
I'm a sh/csh/ksh/awk/sed kinda' guy at heart :)
--
Ron Hall       | DISCLAIMER: I said it. I must've meant it. There is
Analyst        |             nobody else to blame.

+1 514 398 3718    | "Whenever doubt can be called into question, do so."

Sat, 13 Sep 1997 00:37:14 GMT
Help with Arrays of Arrays
: I have a file that looks something like this
:       a:1
:       a:2
:       a:3
:       b:1
:       b:2
:       c:1
:       c:2
: What I what to produce is the following
:       a:
:         1
:         2
:         3
:         b:
:         1
:         2
:       c:
:         1
:         2
: What I have so far gets me the separate indices ( a, b ,c) and a list
: associated with each one. How do I create an associative array so
: that I can index the list?

while (<>) {
chop;
(\$group,\$value) = split(/:/,\$_);

Quote:
}

foreach \$key (sort keys %array) {
print "\$key:\n";
for (\$index = \$[ ; \$index <= \$#{\$array{\$key}} ; \$index++) {
print "    \$array{\$key}[\$index]\n";
}

Quote:
}

This seems to work for me.  Although it may look kinda strange until you
get used to the perl5 way, I THINK this is correct.  More experienced
readers may wish to comment.  Some explanations (correct me if I'm wrong):

\$array{\$group} as a reference to an array, and dereference it.  It would

on-demand if they are not already in existance.

Line 2 is not necessary, it just prints the current value(s) of the array
for debugging purposes.

The foreach should be obvious.

The for statement starts \$index at the value of \$[, which is the "lowest"
index normally used.  The \$#{\$array{\$key}} returns the last index into
the array.  If you have created a sparse array (i.e., you set a[0], a[1],
and a[3], but not a[2]) you may want to check to see if that element is
defined before printing out the results.  Anyone know a better way of
doing this?

Fred

Thu, 18 Sep 1997 04:00:00 GMT
Help with Arrays of Arrays

... solution ...

Looks fine, but

Quote:
>        for (\$index = \$[ ; \$index <= \$#{\$array{\$key}} ; \$index++) {
>                print "    \$array{\$key}[\$index]\n";

is easier said:

or even:

I can't remember using a for ( ; ; ) loop in Perl for ages...

Quote:
>The for statement starts \$index at the value of \$[, which is the "lowest"
>index normally used.  The \$#{\$array{\$key}} returns the last index into

Use of \$[ is deprecated in Perl 5. It's also slightly changed, to make
things more efficient. Beware.

Ian

Thu, 18 Sep 1997 04:00:00 GMT
Help with Arrays of Arrays

Quote:

>: I have a file that looks something like this
>:   a:1
>:   a:2
>:   a:3
>:   b:1
>:   b:2
>:   c:1
>:   c:2
>: What I what to produce is the following
>:   a:
>:     1
>:     2
>:     3
>:         b:
>:     1
>:     2
>:   c:
>:     1
>:     2
>: What I have so far gets me the separate indices ( a, b ,c) and a list
>: associated with each one. How do I create an associative array so
>: that I can index the list?

>while (<>) {
>        chop;
>        (\$group,\$value) = split(/:/,\$_);

>}
>foreach \$key (sort keys %array) {
>        print "\$key:\n";
>        for (\$index = \$[ ; \$index <= \$#{\$array{\$key}} ; \$index++) {
>                print "    \$array{\$key}[\$index]\n";
>        }
>}

He may not want them sorted, (who knows, since the example input was already
sorted) but rather to output them in the same order as input.  Also, foreach
is a lot simpler than looping on array indices, and \$[ and \$# are deprecated.
E.g.,

#!/usr/local/bin/perl5 -w

\$prev='';
while (<>) {
chomp;      # perl5 feature, works even if the last line of the file
# is missing a newline
((\$group,\$value) = /^(.*?):(.*)/) # more flexible than split
|| die "malformed line <\$_>\n";

# each group is represented as a 2-element array, with element [0] being
# the group label and element [1] being an array of values.
# There are, of course, implementations that don't require nested arrays.

#add \$value to the array of values for the last group

Quote:
}

\$group = \$\$pair[0];
print "\$group:\n";
\$indent = ' ' x (length(\$group)+1);

print "\$indent\$value\n";
}

Quote:
}

Of course, this may or may not be what Mr. Hall wants.  The problem with saying
"I want to transform input I into output O" is that you may get a thousand
different programs that do just that, but act totally differently on *other*
inputs.  What you need to do is specify the input in *general* terms and define
the output as a transformation on the abstract elements of the input.  If you
are going to give examples, at least give ones that indicate the kinds of
transformations expected.  The worst sort of example is one where the input
and output are already sorted, since then there is no way to tell whether the
output is supposed to be in sorted order or in input order.

Note that all these programs assume that it is necessary to actually do some
sort of structured operations or transformations to these records.  If not,
then a simple solution that prints the same as the above is

#!/usr/local/bin/perl5 -w

\$prev='';
while (<>) {
chomp;
((\$group,\$value) = /^(.*?):(.*)/) || die "malformed line <\$_>\n";
print \$prev=\$group, ":\n" if \$group ne \$prev;
print ' ' x (length(\$group)+1), "\$value\n";

Quote:
}

--
<J Q B>

Thu, 18 Sep 1997 04:00:00 GMT

 Page 1 of 1 [ 4 post ]

Relevant Pages