Updated: 2017-10-01-Sun 20:03:37 Z
In Perl, an array is simply a collection of scalar variable elements.
Arrays in Perl are much like arrays in many other languages, and, like many scripting languages, the number of items in the set can change
over time (in contrast to, e.g., C or Java in which the size of the array must be set upon initial creation).
Perl uses the @ symbol to signify an array. You must remember that we use the @ in our Perl code ONLY when we mean the entire array as an entire set; in contrast, we refer to single items of the array in a different manner (which we'll see soon).
Let's look at a code example that instantiates/declares/creates an empty array called 'foo' and exits with the array being empty (i.e., have 0
elements) and thus undef
:
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
# now the array foo exists yet is empty and undef.
exit;
In the above example, the array 'foo' was created and, as we added nothing to it, it was an undefined set of 0 scalar variable elements.
Let's look at en example where we initialize the array to have values.
In the following example, we create an array 'foo' and initialize to it have a few items at the same time that we declare the array.
#!/usr/bin/perl
use strict;
use warnings;
my @foo = ( 42, "hi everyone", 16 );
# now the array foo exists and has 3 scalar items in it.
exit;
Let's look at an example in which we create/declar/instantiate an empty array, then assign 3 scalar values/elements to it, then reassign 3 new values to it.
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
# We used 'my' only upon first reference of the array,
# then we don't use 'my' with that array again !
# Why ? Because that's just the rule as we learned it.
@foo = ( 42, "hi everyone", 16 );
# now the array foo exists and has 3 scalar items in it.
@foo = ( "go", 99, 411 ) ;
# now the array foo has - still - 3 (new) scalar elements in it.
exit;
Let's move away from thinking about the array as a whole and think about the individual scalar items/elements in the set that we create as an
array. We have a way of referencing the array foo as a whole - i.e., @foo
, but how do we refer to
individual items in the array?
Important: what we haven't mentioned so far is that items in an array in Perl (and in many languages) are in a numbered order.
Which order?
... The order in which you defined them when you added them to the array.
To refer to individual items in the array, we use a whole number to describe which scalar element in the set we're talking about.
So, if we have a piece of code that looks like the following -
my @my_set = ( 19, "hello", 42 ) ;
- we can make the following assertions about the array:
$#my_set
is 2. (the index of the last item).
Since we're talking about the individual items/elements in an array, how do we reference them individually?
We need 3 things to reference an individual item/element in an array:
print $my_set[1] . "\n"; # remember - index 1 is the 2nd element.
Let's pause for a moment and think about remembering these rules when we look at code or want to write it.
@foo means the entire array foo.
When we talk about 1 item/element in an array,
OUR EYES NEED TO SEE SQUARE BRACES AFTER THE ARRAY NAME WITH A WHOLE NUMBER THEREIN and THE
DOLLAR-SIGN IN FRONT OF THE ARRAY NAME TO SIGNIFY WE'RE TALKING ABOUT JUST ONE OF THE SCALARS IN THE ARRAY.
Let's look at some code we've seen somewhere above - create the array foo, then set stuff in it, then some new stuff in it, and then try to empty it.
The following is NOT the way to empty an array...
It's the way to put 1 undefined value in it.
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
@foo = ( 42, "hi everyone", 16 );
# now the array foo exists and has 3 scalar items in it.
@foo = ( "go", 99, 411 ) ;
# now the array foo has - still - 3 (new) scalar elements in it.
@foo = undef ;
# Warning: This is similar to saying -
# @foo = ( undef ) ;
# - which means the array will have 1 undefined scalar in it.
exit;
There are at least 3 ways to completely remove all the scalar items in an array.
Remember - there are always a lot of ways to accomplish something in Perl (joy!).
#!/usr/bin/perl
use strict;
use warnings;
my @foo;
@foo = ( 42, "hi everyone", 16 );
# now the array foo exists and has 3 scalar items in it.
@foo = () ; # nothing in the array now.
undef @foo; # still empty ! :)
$#foo = -1; # and still nothing in it.
# The one above means 'Set the last index of the array foo to -1'.
# Warning/Review:
@foo = undef;
# Not empty now; has something in it.
exit;
In the previous example, notice that one way to empty an array is to use the following:
$#foo = -1 ;
What is this?
It means 'set the highest index number to -1.'
But why don't we use 0 in that case to empty an array?
Because 0 is the first index number in an array and so if we wrote
$#foo = 0; #wrong if you're trying to empty an array!
then we'd be saying the highest index is 0 (which is an array of size 1, not an empty array).
Since we're talking about -1, let's learn another rule about Perl.
Perl allows you to refer to the last element in an array with -1. Remember that the first element is at array index 0 and the number goes up, or you can refer to the end of the array in regards to the 0-index as a negative number counting down from the top.
So, if we use that piece of code from before and add the above info to our knowledge of that code -
my @my_set = ( 19, "hello", 42 ) ;
$#my_set
is 2. (the index of the last item).
Often you will need to know how many items are in the array.
One way to do this and store the array size in a variable is as follows:
#!/usr/bin/perl
use strict;
use warnings;
my $size_of_foo = scalar( @foo ) ;
# or simply use scalar without parens -
# my $size_of_foo = scalar @foo ;
# OR you can just write something like
my $size = @foo ;
# And since you learned in a prior example that
# $#foo means the index number of the last scalar element,
# you could also calculate size like this -
$size_of_foo = $#foo + 1;
exit;
For the array 'foo', we can use @foo
to refer to the entire array and it can mean the size of the array
(DEPENDING ON CONTEXT).
syntax $#foo
to get this information.
WARNING: Be careful when using the array in a print statement. In the following code, the 3 print statements do interpret the array in very different ways.
#!/usr/bin/perl
use strict;
use warnings;
my @my_set = ( 19 , "hello" , 42 ) ;
print "Ex. 1. --->" . @my_set . "<---\n";
print "Ex. 2. --->" , @my_set , "<---\n";
print "Ex. 3.--->@my_set<---\n";
#So what do they produce ?
exit;
The code above produces the following output:
Ex. 1. --->3<---
Ex. 2. --->19hello42<---
Ex. 3. --->19 hello 42<---
Example 1 - the size of the array (or number of scalar elements).
Example 2 - using the commas - appends all the contents of array together without spaces.
Example 3 - using the array inside double-quotes interpolates the contents (places a space between each item).
How can we add to and remove from an array?
One trick is to just set the new value of the array to a list containing the original array and new items.
#!/usr/bin/perl
use strict;
use warnings;
my @my_set = ( 19, "hello", 42 ) ;
# now set a new value for the array to be -
# what it was plus add some new items to the end.
@my_set = ( @my_set , 88, "99" ) ;
# Now the array has its original items, but we've also added
# into index 3 - the fourth element - the numeric 88, and
# into index 4 - the fifth element - the string containing two '9' characters.
# Let's remove the "99" string with the pop() function...
pop( @my_set ) ;
# Now the array has just 4 items - ( 19, "hello", 42, 88 )
# Let's get rid of the 19 at the front...
shift( @my_set ) ;
# Now the array has just 3 items - ( "hello" , 42, 88 )
# Let's get rid of the 88...
pop @my_set ;
# Now the array has just 2 items - ( "hello" , 42 )
# Here's a cool way to move the end of the array to the front...
unshift( @my_set , pop(@my_set) ) ;
# We removed the end and stuck it onto the front -
# so the array contains the same 2 items
# (in different ordering) - ( 42, "hello" )
# Let's put the 42 back on the end with the following -
push( @my_set , shift( @my_set) ) ;
# Now we're pushed onto the end of the array - what?
# Well, that which we removed from the front of the array.
exit;
By the way, you must know this terminology.
You know what an array is so far, but what do we call the items in parentheses?
They are called LISTS.
And so a statement like the following -
my @foo = ( 7, "hi", 8 ) ;
- is called LIST ASSIGNMENT OF AN ARRAY.
Any other interesting things to learn about arrays?
If I set the value of an index that didn't previously exist, all lower-numbered indices that also did not exist shall be set to undef - as seen in the following example:
#!/usr/bin/perl
use strict;
use warnings;
my @foo ; # created an empty array called foo.
$foo[2] = "hello" ;
# now $foo[0] is undef
# and $foo[1] is undef
# and $foo[2] is "hello"
exit;
Can we completely reverse an array?
YES, but think it out!!!
Ask yourself first what you want to do?
Do you need to completely reverse the ordering inside some array @foo?
# This permanently changes @foo to reverse order.
@foo = reverse( @foo ) ;
# This code does something, but what?
reverse @foo ;
What about printing the contents of an array - one element per line?
#!/usr/bin/perl
use strict;
use warnings;
my @foo = ( 19, "hello", 7 ) ;
# The following will all do the same thing...
foreach ( @foo ) {
print "$_\n";
}
foreach my $elt ( @foo ) {
print $elt . "\n";
}
for ( my $i = 0; $i < @foo ; $i++ ) {
print "$foo[$i]\n";
}
my $c = 0; # initilize to 0 !!!
while ( $c < @foo ) {
print $foo[$c] . "\n";
$c++;
}
$c = 0; # initilize to 0 again !!!
while ( $c < @foo ) {
print $foo[$c++] . "\n";
}
exit;
Here's something cool we do a lot with Perl.
We can change stuff using the split function.
Let's say we have 3 items - all the same -
3 strings that each contain a student name
followed by a colon and then the student's ID.
If we want to permanently change the contents so that
there is a tab before and after the colon, we could do
something like the following:
#!/usr/bin/perl
use strict;
use warnings;
my @name_id = ( "Vikram:E883" , "Joe:E289" , "Ryan:E888" ) ;
for ( my $i = 0 ; $i < @name_id ; $i++ ) {
my @temp = split( /:/ , $name_id[$i] ) ;
$name_id[$i] = $temp[0] . "\t:\t" . $temp[1] ;
}
exit;