newbie2perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi All, Thanks very much to all who responded to my first post, very informative and I got it to work! I have one more question. When searching initially, I searched based on elements in a 1D array. I now want to search based on something modeled after a 2D array. So the structure would hold the name and type of an object, search for a match of the name in that file, and return the name and type of any name found in the file. So, if the structure contained the following values:
structure = { name1, type1; name2, type2; name3, type3; name4, type4 };
The search would match name1 to the data contained in the file, and if found, store the name1 and type1 into another structure. It would do this for each name in the structure and store both the name and type for any name string found in the file. What is the best way to do this? I would like to stay away from a 2D array if possible, and am wondering if there is some kind of array of structures I use. Again, any help or advice is welcomed. Thanks!

Replies are listed 'Best First'.
Re: Creating an array of structures?
by davido (Cardinal) on Mar 08, 2005 at 05:59 UTC

    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

      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

      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.
Re: Creating an array of structures?
by lidden (Curate) on Mar 08, 2005 at 05:59 UTC
    You want a hash:
    my %foo = ( name1 => type1, name2 => type2, name3 => type3, name4 => type4, ); print $foo{name2}, "\n";
    Se "perldoc perldsc" if you need more complicared structures.

    Update: Oops I mostly copied the OP. Changed as suggested by davido. Note to self : dont post at 7 AM.
      my %foo = ( name1, type1; name2, type2; name3, type3; name4, type4 ); print $foo{name2}, "\n";

      I realize that's probably just pseudo-code, but we ought to get the syntax right anyway. :)

      my %foo = ( name1 => 'type1', name2 => 'type2', name3 => 'type3', name4 => 'type4' ); print $foo{name2}, "\n";

      In particular, note the use of ',' (comma) instead of ';' (semicolon) between list items.


      Dave

Re: Creating an array of structures?
by Squall` (Initiate) on Mar 08, 2005 at 14:41 UTC
    Firstly, Perl doesn't have static types, which you are probably implying, like int, char, and even classes. Read perldata for more information. You may also want to check out Class::Struct.