in reply to Creating an array of structures?

What you are describing is an array of arrays (AoA), which is pretty much a 2D array. Why do you wish to avoid what may be the best tool? Of course if the names field is unique (ie, you never have duplicates) you could also represent your datastructure as a hash of arrays (HoA).

In Perl, a 2D array is really just a narrow subset of what is broadly described by the word "datastructure". And you can read all about manipulating complex datastructures in the perldocs (POD). perllol = "Perl lists of lists", perldsc = "Perl datastructure cookbook", and of course perlreftut = "Perl references tutorial". After reading through those documents (consider them your homework assignment -- they'll take you an hour or so) you'll be much better equipped to answer the very questions you're asking here.


Dave

Replies are listed 'Best First'.
Re^2: Creating an array of structures?
by newbie2perl (Initiate) on Mar 08, 2005 at 06:35 UTC
    Hi Dave, Thanks for steering me towards the literature. I took a quick look at the perllol and see how the AoA structure can do what I want. I will look at the restof the readings tomorrow, it's getting a bit late for me on this coast. I'm not quite sure why I was told to possibly avoid 2D arrays, it was some advice I was given at some point today. I will ask more questions to ascertain why and get back to you if you are interested. Thanks again for the pointers, will post something later as I learn more about how to do what I want to do.

      Please do feel free to post some specific questions as you get further into the project (or into the reading). We love helping to solve problems.

      It's possible that you were steered away from a 2D array, in favor of some other Perl datastructure, such as a hash of arrays (which is also a 2d structure, but built using two types of simple datastructures instead of a single type).

      It may be helpful to remember that in Perl, complex datastructures are easily built on-the-fly, and thus, can be made to any degree of complexity. The shape or topography of a Perl complex datastructure is limited only by need and imagination.


      Dave

Re^2: Creating an array of structures?
by Tanktalus (Canon) on Mar 08, 2005 at 15:01 UTC
    Why do you wish to avoid what may be the best tool?

    There is one really obvious answer to that. It's the same as wanting to do linked lists in C while avoiding the use of pointers. It takes a bit to wrap one's head around some of these concepts (it took me two months to wrap my head around pointers in C, but, once I did, the whole language became trivial). Avoiding them before you understand them is a bit like avoiding the dark - a bit of fear of the unknown. Part of what we do here, and what the PODs you referenced (no pun intended ;-}) do, is to dispell that lack of understanding so that newer Perl users no longer fear them.

    I'd love to see newbie2perl's "advisor" post here as well to dispell his/her fear of the unknown as well :-)

      Hi Tanktalus, My Advisor is not available yet today, so I haven't been able to ask further questions as to why to stay away from 2D arrays like AoA, HoA, AoH, and HoH. In the meantime I've tried to get a handle of how to populate a 2D array from results returned from a select statement run against a database. I can't quite seem to understand how to do so, I have tried many methods, but none populate the array properly. I either get a blank array or nothing happens. Below is an example of what I have thus far:
      use strict; my ($object_name, $object_type, $module_type, @list_of_objects, $database, $userid, $passwd); $database = 'DBI:Oracle:tdtxtasd'; print "Please enter your username:"; $userid = <STDIN>; chomp($userid); print "Please enter your password:"; $passwd = <STDIN>; chomp($passwd); use DBI; my $dbh = DBI->connect($database, $userid, $passwd) or die "Couldn't connect to database: " . DBI->errstr; my $sth = $dbh->prepare('SELECT object_name, object_type FROM user_obj +ects WHERE object_type = ?') or die "Couldn't prepare statement: " . $dbh->errstr; $module_type = "PROCEDURE"; my $rc = $sth->execute($module_type); while (($object_name, $object_type) = $sth->fetchrow()) { #push @{list_of_objects},$object_name, $object_type; print "$object_name $object_type\n"; }; $dbh->disconnect;
      I know the "#push @{list_of_object},$object_name, $object_type;" line is wrong, but am not sure how to populate what I want to be a 2D array (@list_of_objects) with the two variables returned for each row ($object_name and $object_type). Additionally, once this occurs, how will I be able to reference just the $object_name from this array for each element in the array to then search a document for each $object_name. Is it a case of using foreach loops to reference each dimension in the array? Such as(extreme pseudocode to follow:
      foreach i (1....n) { foreach j (1,2) { $object_name = @list_of_values[i][2]; } };
      I realize this is a long post. I hope I get my point across. Let me know what you think. Thanks.

        I'll embed some comments in your code.

        # good idea :-) use strict; # There are many theories on why this is a bad idea. # My personal favourite is keeping the scope of a variable # as small as possible. Larger scope means that when I'm # trying to read your code, I need to go back farther in # the program to find out it's a lexical, and to find out # who may have changed the value. # Another reason I know to change this is to create and initialise # the variable at the same time - it means having no undef # variables (unless you explicitly want it to be undef). # For example, there is no reason to have $database undefined. # That would be an error. By combining the my with the # initialisation, then there is no point in the program # where you could be accessing an undefined $database. #my ($object_name, # $object_type, # $module_type, # @list_of_objects, # $database, # $userid, # $passwd); # create/initialise. my $database = 'DBI:Oracle:tdtxtasd'; print "Please enter your username:"; my $userid = <STDIN>; chomp($userid); print "Please enter your password:"; # You can super-search on passwords - there are ways to # do this without echoing to the screen. I think it's # in code snippets - and I think I contributed to it ;-) my $passwd = <STDIN>; chomp($passwd); # some people put all use's at the top. Some put them # close to where they're used. I'm not convinced one is # better than the other, so this is just FYI. use DBI; # here's a my which initialises. Good choice :-) my $dbh = DBI->connect($database, $userid, $passwd) or die "Couldn't connect to database: " . DBI->errstr; my $sth = $dbh->prepare('SELECT object_name, object_type FROM user_obj +ects WHERE object_type = ?') or die "Couldn't prepare statement: " . $dbh->errstr; my $module_type = "PROCEDURE"; my $rc = $sth->execute($module_type); my @list_of_objects; while (($object_name, $object_type) = $sth->fetchrow()) { print "$object_name $object_type\n"; # push a scalar onto the list. That scalar is an array ref. # in this case, a ref to an anonymous array. push @list_of_objects, [ $object_name, $object_type ]; }; $dbh->disconnect;
        To read it back out:
        foreach my $object (@list_of_objects) { my @values = @{$object}; # do whatever. }
        Hope that helps!