Home > Archive > PERL Beginners > October 2006 > Indexing an array inside an array of pointers to a hash
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Indexing an array inside an array of pointers to a hash
|
|
| bl8n8r 2006-10-07, 7:58 am |
| I'm trying to index an array inisde an array of pointers to a hash, but
not quite sure how to do it. Anyone have some tips? This is what I
have so far.
Thanks!
----------------------------------------------------------------------------------------
#!/usr/bin/perl
use strict;
use warnings;
# maximum number of @Info hash entries to create
# mostly for debugging..
my $MAXHASH = 5;
#
# maximum number of friends to allow (debugging anyway)
#
my $MAXFRND = 7;
#
# hash to hold people info
#
my @Info =
{
name => my $realname,
nick => my $nickname,
frnd => my @friends
};
#
# print any messages here
# pass : 1 message, 2 exit_TORF
# ret : none
#
sub Error (@)
{
my ($msg, $exitcode) = @_;
print "***Error: $1\n";
if ($exitcode == 1)
{
print "Terminating.";
exit 1;
}
}
#
# print array contents
# pass : none
# ret : none
#
sub PrintArray()
{
my $idx = 0;
my $cidx = 0;
my $name = ""; # make some variable to use in the loop for ease
my $nick = "";
my @buf;
# fill hash with some random entries
for ($idx = 0; $idx < $MAXHASH; $idx++)
{
$name = $Info[$idx]->{name};
$nick = $Info[$idx]->{nick};
print "\n\n";
print "hash element $idx)\n";
print "------------------------------------\n";
print "NAME : $name\n";
print "NICK : $nick\n";
print "FRIENDS : ";
# print array elements contained within the current hash index
for ($cidx = 0; $cidx < $MAXFRND; $cidx++)
{
print ${ $Info[$idx]->{frnd}[$cidx] }." ";
}
}
}
#
# start here
#
sub Main()
{
my $idx = 0;
my $cidx = 0;
my $tmp = "";
my @buf;
print "filling hash...\n";
# fill hash with some random entries
for ($idx = 0; $idx < $MAXHASH; $idx++)
{
$Info[$idx]->{name} = "name_".int(rand(100));
$Info[$idx]->{nick} = "nick_".int(rand(100));
print "friends for $Info[$idx]->{name} at index $idx...\n";
# omfg...
for ($cidx = 0; $cidx < $MAXFRND; $cidx++)
{
# use a temp var here so we can print out the random
$tmp = "frnd_".int(rand(100));
# index the array inside the pointer to the hash
${ $Info[$idx]->{frnd}[$cidx] } = $tmp;
print " $cidx)$tmp";
}
# some whitespace on output
print "\n\n";
}
}
# fire it up
Main();
PrintArray();
| |
| nobull67@gmail.com 2006-10-07, 7:00 pm |
|
On Oct 7, 2:50 pm, "bl8n8r" <bl8...@yahoo.com> wrote:
> I'm trying to index an array inisde an array of pointers to a hash, but
> not quite sure how to do it. Anyone have some tips?
What do you mean by "to index"?
> This is what I have so far.
>
> Thanks!
>
> ----------------------------------------------------------------------------------------
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
Good start. But do you know why we do this?
> # maximum number of @Info hash entries to create
> # mostly for debugging..
> my $MAXHASH = 5;
>
> #
> # maximum number of friends to allow (debugging anyway)
> #
> my $MAXFRND = 7;
>
> #
> # hash to hold people info
> #
Comments have their uses but they should add information not restate
what can be seen by looking at the code. Comments that simply describe
the code are of little or no value. Comments that innacurately describe
the code are of negative value as they can often cause people reading
the code to see what the comment leads them to expect to see, not what
is there.
> my @Info =
> {
> name => my $realname,
> nick => my $nickname,
> frnd => my @friends
What to you think that does? You never use those variables.
>
> };
@Info is an array of hashes, not a hash.
> # print any messages here
> # pass : 1 message, 2 exit_TORF
> # ret : none
> #
> sub Error (@)
Protypes in Perl5 are generally a bad idea. Avoid them.
> {
> my ($msg, $exitcode) = @_;
>
> print "***Error: $1\n";
>
> if ($exitcode == 1)
> {
> print "Terminating.";
> exit 1;
> }
>
> }#
> # print array contents
> # pass : none
> # ret : none
> #
> sub PrintArray()
> {
> my $idx = 0;
> my $cidx = 0;
> my $name = ""; # make some variable to use in the loop for ease
> my $nick = "";
Nasty case of premature declaration you've got there.
What it the point of storing the values 0 and "" in those variables?
You never use them. Try to use the natural representation of things.
The natural representation of a scalar not containing anything is the
undef value. And that's the value that scalars start out with.
> my @buf;
You never use that variable. This is one of the unfortuate side effects
of premature declaration. By separating the declaration from the use
you often end up with declarations for variables left behind when you
remove code.
> # fill hash with some random entries
This comment appears to have nothing to do with the code. Again bad
comments are worse than no comments.
> for ($idx = 0; $idx < $MAXHASH; $idx++)
This is better written
for my $idx ( 0 .. $MAXHASH - 1 )
However surely $MAXHASH is the _maximum_ number of hashes in @info but
if you are trying to print ount the contents of a @info you should care
about the _current_ number
for my $idx ( 0 .. $#Info )
> {
> $name = $Info[$idx]->{name};
> $nick = $Info[$idx]->{nick};
This is where you first use these variables so this is where you should
have decalred them.
my $name = $Info[$idx]->{name};
my $nick = $Info[$idx]->{nick};
> print "\n\n";
> print "hash element $idx)\n";
> print "------------------------------------\n";
> print "NAME : $name\n";
> print "NICK : $nick\n";
> print "FRIENDS : ";
>
> # print array elements contained within the current hash index
> for ($cidx = 0; $cidx < $MAXFRND; $cidx++)
for my $cidx ( 0 .. $#{ $Info[$idx]->{frnd} } )
> {
> print ${ $Info[$idx]->{frnd}[$cidx] }." ";
You should probaby keep or omit your optional -> completely within any
given varialble reference.
print ${ $Info[$idx]->{frnd}->[$cidx] }." ";
or
print ${ $Info[$idx]{frnd}[$cidx] }." ";
Anyhow what's with the extra level of scalar ref? Why not just store
the data directly in the array?
print $Info[$idx]{frnd}[$cidx] ." ";
But you never use $cidx except as a subscript, so you may as well loop
over the elements of the list directly.
for ( @{ $Info[$idx]{frnd} } )
{
print $_ ." ";
}
> }
> }
>
> }#
> # start here
> #
> sub Main()
> {
> my $idx = 0;
> my $cidx = 0;
> my $tmp = "";
Again with the premature declaration. Again with the meaningless
initialisation.
> my @buf;
Again with the unused variable.
> print "filling hash...\n";
>
> # fill hash with some random entries
> for ($idx = 0; $idx < $MAXHASH; $idx++)
> {
> $Info[$idx]->{name} = "name_".int(rand(100));
> $Info[$idx]->{nick} = "nick_".int(rand(100));
>
> print "friends for $Info[$idx]->{name} at index $idx...\n";
>
> # omfg...
Engh?
> for ($cidx = 0; $cidx < $MAXFRND; $cidx++)
> {
> # use a temp var here so we can print out the random
> $tmp = "frnd_".int(rand(100));
>
> # index the array inside the pointer to the hash
> ${ $Info[$idx]->{frnd}[$cidx] } = $tmp;
>
> print " $cidx)$tmp";
> }
>
> # some whitespace on output
Again with the unhelpful comments. You print two newlines. This is
selfevident. Whist it is true that newline characters are whitespace
the comment adds nothing.
> print "\n\n";
>
> }
>
> }# fire it up
> Main();
> PrintArray();
Right now I've cleaned up the code but I still don't know what you were
asking...
#!perl
use strict;
use warnings;
# maximum number of @Info hash entries to create
# mostly for debugging..
my $MAXHASH = 5;
#
# maximum number of friends to allow (debugging anyway)
#
my $MAXFRND = 7;
#
# array of hashes to hold people info
#
my @Info;
#
# print array contents
# pass : none
# ret : none
#
sub PrintArray {
for my $idx ( 0 .. $#Info )
{
my $name = $Info[$idx]->{name};
my $nick = $Info[$idx]->{nick};
print "\n\n";
print "hash element $idx)\n";
print "------------------------------------\n";
print "NAME : $name\n";
print "NICK : $nick\n";
print "FRIENDS : ";
# print array elements contained within the current hash index
for ( @{ $Info[$idx]{frnd} } )
{
print $_ ." ";
}
}
}
#
# start here
#
sub Main {
print "filling hash...\n";
# fill hash with some random entries
for my $idx ( 0 .. $MAXHASH - 1 )
{
$Info[$idx]->{name} = "name_".int(rand(100));
$Info[$idx]->{nick} = "nick_".int(rand(100));
print "friends for $Info[$idx]->{name} at index $idx...\n";
for my $cidx ( 0 .. $MAXFRND - 1 )
{
# use a temp var here so we can print out the random
my $tmp = "frnd_".int(rand(100));
$Info[$idx]{frnd}[$cidx] = $tmp;
print " $cidx)$tmp";
}
print "\n\n";
}
}
# fire it up
Main();
PrintArray();
__END__
| |
| bl8n8r 2006-10-07, 7:00 pm |
| nobull67@gmail.com wrote:
> On Oct 7, 2:50 pm, "bl8n8r" <bl8...@yahoo.com> wrote:
>
> What do you mean by "to index"?
>
>
> Good start. But do you know why we do this?
good question. One of the things 'strict' does is it wont
let you use variables until you declare them, or warn you
if you've mistyped one. Very handy indeed.
'use warnings' will warn you if you do not initialize a variable
before you use it. Such as:
[1]$ perl -e 'use warnings; my $foo; print $foo;'
Use of uninitialized value in print at -e line 1.
[1]$ perl -e 'use warnings; my $foo = 0; print $foo;'
0
> However surely $MAXHASH is the _maximum_ number of hashes in @info but
> if you are trying to print ount the contents of a @info you should care
> about the _current_ number
>
> for my $idx ( 0 .. $#Info )
Interesting.. That gives the number of items-1 in @Info.
No need for a less-than operator in the for loop?
> You should probaby keep or omit your optional -> completely within any
> given varialble reference.
>
> print ${ $Info[$idx]->{frnd}->[$cidx] }." ";
>
> or
>
> print ${ $Info[$idx]{frnd}[$cidx] }." ";
Cool. I didn't know the '->' operator was optional for reference.
Is it only used for assignment then?
> # use a temp var here so we can print out the random
> my $tmp = "frnd_".int(rand(100));
>
> $Info[$idx]{frnd}[$cidx] = $tmp;
Awesome. Thanks!
| |
| Paul Lalli 2006-10-07, 7:00 pm |
| bl8n8r wrote:
> nobull67@gmail.com wrote:
>
> Interesting.. That gives the number of items-1 in @Info.
> No need for a less-than operator in the for loop?
There is rarely a need for a C-style for loop in Perl. The above is a
"foreach style" loop. But 'for' and 'foreach' are synonyms in Perl, so
anywhere you see "foreach" you can replace it with "for".
Read:
`perldoc perlsyn` for foreach loops
`perldoc perldata` for the $#array notation
>
>
> Cool. I didn't know the '->' operator was optional for reference.
> Is it only used for assignment then?
No. The arrow is optional when it's between two brackets (either [] or
{}). Doesn't matter if you're reading or writing to the reference.
perldoc perlreftut
Paul Lalli
|
|
|
|
|