in reply to Re^3: simple array question
in thread simple array question

Glad to help a new Perler starting on the journey.

Let me congratulate you on some stuff that you definitely did right! You thought about the problem yourself, you showed some code that you had written and what that code did, and asked a clear question. Basically the more work that you are doing, the more help that you are going to get.

I suspect that a next question is going to be "how do I print this?". So, see below...

I made a new blank array, @another_compass. Then to populate this, I showed some push operations instead of a fixed declaration statement. Just like @compass, @another_compass contains references to arrays. Essentially, what [ "NW", "N", "NE" ] means, is allocate some new memory (which has no name known to the program), an "anonymous array" and put 3 things in it, "NW", "N", "NE". Then the reference to that memory is pushed onto @another_compass.

To print this, each thing in @another_compass is a reference to an array. So, I iterate over each reference. @$compass_row says to expand this reference to an array back into the original array. Enclosing @$compass_row in quotes causes a space to be inserted between elements. Try it without the quotes.

Indicies can be used in Perl, but Perl has many iterators that help avoid having to do that. "off by one" errors are some of the most common boo-boos in programming. Using a Perl iterator avoids that problem by dispensing with the index all together. Of course there are times when our buddy, [ i ] is needed.

The Data::Dumper module is a fantastic tool for easily printing complex Perl structures. play with that too!

Have fun!

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @compass = ( ["NW", "N", "NE"], ["W", "center", "E"], ["SW", "S", "SE"], ); my @another_compass; push (@another_compass, ["NW", "N", "NE"]); push (@another_compass, ["W", "center", "E"]); #print Dumper \@another_compass; # uncomment to see what this does print "Dumping another_compass...\n"; foreach my $compass_row (@another_compass) { print "@$compass_row\n"; } __END__ Prints: Dumping another_compass... NW N NE W center E

Replies are listed 'Best First'.
Re^5: simple array question
by tw (Acolyte) on Jan 03, 2011 at 12:36 UTC

    Thanks for the encouragement Marshall

    You have partly anticipated my next hurdle

    I am ok with using foreach to loop through all the elements but am struggling with returning particular values....for example if I only wanted to return the first value of @another_compass into a new array. i.e.

    NW W SW

    have tried a number of things similar to this...

    my @first_value = (); for my $compass_row (@another_compass) { push (@first_value, shift); }
    but obviously not correct, I used a split in place of shift with a slightly different problem so I thought shift would work. Although i assume you would need a different solution if the second value was required. Any pointers will be appreciated.
      One very powerful operation in Perl is the "list slice". The code below shows a general application of that concept.

      With a list slice, you can say: "I want the first element of an array, the last element of an array, and the the second element of an array", and assign those things to variables on the left hand side of the equals sign. WOW!

      Here, [ 0,-1,1 ] look like indicies, but they aren't really the same thing. For example, [ -1 ], what kind of index is that? None. That -1 means the last thing in the list.

      I am currently working with a database output that has hundreds of things on a line. I can assign the 89th thing, the 21st thing to Perl variables. my ($name,$address) = (@stuff)[ 88, 20 ]. The other things don't matter and I don't have to assign say, $zip_code to something that I am not going to use later in the code.

      #!/usr/bin/perl -w use strict; my @compass = ( ["NW", "N", "X", "NE"], ["W", "center", "X", "E"], ["SW", "S", "X","SE"], ); foreach my $compass_row (@compass) { my ($first, $last, $second) = (@$compass_row)[0,-1,1]; my ($only_first) = (@$compass_row)[0]; print "only the first thing: $only_first\n"; print " first=$first last=$last second=$second\n"; } __END__ Prints: only the first thing: NW first=NW last=NE second=N only the first thing: W first=W last=E second=center only the first thing: SW first=SW last=SE second=S
      Oh, of course $first and $only_first are the same. I assigned different variables to emphasize that there is no connection between the first and second list slice statements.

        yeah wow, really cool and powerful. I had heard perl is really good for that sort of thing. I'm learning it initially to do a transformation on csv files with an unusual layout to import into a database. I've used sed, awk and some simple scripting before but no serious programming and the perl code can be so compact I can have trouble decoding it. I have a bit to learn.

        I can see how you're example works and can execute it. Been trying to apply it to another example but I've got a feeling my array might be a bit messed up - not getting positive results yet.

        Thanks for your time.

      Split is used to separate a single string into multiple items.
      #!/usr/bin/perl -w use strict; my $compass_string = "NW N X NE"; my @headings = split(/\s+/,$compass_string); foreach my $heading (@headings) { print "$heading\n"; } __END__ prints: NW N X NE