Richard's Perl Step 04
Stacking Building Blocks: Lists and Arrays



- I used "Sams Teach Yourself Perl in 24 Hours" - 3rd Edition as a reference for this page
- Run in windows DOS prompt
perl thisprogram.pl

perl c:\......\thisprogram.pl

 

Examples following Perl 24 hours book, Hour 4:

eg006.pl (text only) - list (array), loop through array, size, split

eg007.pl (text only) - list (array) as stack, push/pop, shift/unshift

 

Scalars are Perl's singular nouns. When you need to talk about many things in Perl, you use list data.

Lists are the simplest representation of list data. A list is simply a group of scalars. Sometimes they're written with a set of parentheses encasing the scalars, which are separated by commas. For example, (2, 5, $a, "Bob").

To store list data so that you can refer to it throughout your program, you need an array variable. Array variables are represented in Perl with an "at" sign (@) as the type identifier followed by a valid variable name. For example, @foo .

Putting Things into Lists and Arrays

(5, 'apple', $x, 3.14159)

If the list contains only simple strings, Perl provides a shortcut—the qw operator:
qw( apples oranges 45.6 $x )
This code works just as though you had written the following:
('apples', 'oranges', '45.6', '$x')

Perl also has a useful operator that works in literal lists; it's called the range operator.
(1..10, 20..30);
The preceding example creates a list of 21 elements: 1 through 10 and 20 through 30. Giving the range operator a right operand less than the left, such as (10..1), produces an empty list.

Arrays

Literal lists are usually used to initialize some other structure: an array or a hash. To create an array in Perl, you can simply put something into it. With Perl, unlike other languages, you don't have to tell it ahead of time that you're creating an array or how large the array is going to be.

@boys=qw( Greg Peter Bobby );
After that code runs, the array @boys contains three elements: Greg, Peter, and Bobby.

Array assignments can also involve other arrays or even empty lists, as shown in the following examples:
@copy=@original;
@clean=();

If a literal list contains other lists, arrays, or hashes, these lists are all flattened into one large list.
@boys=qw( Greg Peter Bobby );
@girls=qw( Marcia Jan Cindy );
@kids=(@girls, @boys);
@family=(@kids, ('Mike', 'Carol'), 'Alice');

the preceding snippet for building @family is equivalent to this assignment:
@family=qw(Marcia Jan Cindy Greg Peter Bobby Mike Carol Alice);

The left side of an array assignment can be a list if it contains only variable names.
($a, $b, $c)=qw(apples oranges bananas);
Here, $a is initialized to 'apples', $b to 'oranges', and $c to 'bananas'.

Getting Elements Out of an Array

If the list on the left contains an array, that array receives all the remaining values from the right side.
($a, @fruit, $c) = qw (peaches mangoes grapes cherries);
In this example, $a is set to 'peaches'. The remaining fruits in the list on the right are assigned to @fruit on the left. No elements are left for $c to receive a value. so $c is set to undef.

It's also important to note that if the left side contains more variables than it has elements, the leftover variables receive the value undef. If the right side has more variables than the list on the left has elements, the extra elements on the right are simply ignored.

Getting Elements Out of an Array

Get the contents of the entire array
print "@array";
An array in double quotes is interpolated, and its elements are returned separated by spaces.

@trees=qw(oak cedar maple apple);
print $trees[0]; # Prints "oak"
print $trees[3]; # Prints "apple".
$trees[4]='pine';

(Scalars are also indicated by a dollar sign because they're singular as well. You should notice a pattern here.)

You can also talk about a subgroup within an array, called a slice. @ type identifier and square brackets
@trees=qw(oak cedar maple apple cherry pine peach fir);
@trees[3,4,6]; # Just the fruit trees
@conifers=@trees[5,7]; # Just the conifers


Finding the End of an Array

The first is a special variable in the form $#arrayname. It returns the number of the last valid index of the array.
@trees=qw(oak cedar maple apple cherry pine peach fir);
print $#trees;

prints the number 7.

The other method of finding the size of an array is to use the array variable in a place where a scalar is expected
$size=@array;

You can also specify negative indexes for arrays. Negative index numbers start counting from the end of the array and work backward. For example, $array[-1] is the last element of @array, $array[-2] is the next to the last element, and so on.


Learning More about Context

What is context? Context means the things that surround an item of interest to help define what that item means.
The two most important contexts in Perl are list context and scalar context.

$a=$b; # Scalar on the left: this is scalar context.
@foo=@bar; # Array on the left: this is list context
($a)=@foo; # List on the left: this is also list context.
$b=@bar; # Scalar on the left: this is scalar context.

@mydata=qw( oats peas beans barley );
if (@mydata)
{ print "The array has elements!\n"; }

Here, the array @mydata is evaluated as a scalar, and it returns the number of elements—in this case, 4. The number 4 evaluates to true.


Context with Operators and Functions

The print function expects a list as an argument. It doesn't particularly matter what context the list is evaluated in, though. So printing an array with print like this causes the array to be evaluated in a list context, yielding the elements of @foo:
print @foo;
You can use a special pseudofunction called scalar to force something into a scalar context:
print scalar(@foo);

The chomp function takes either an array or a scalar as an argument. If chomp is presented with a scalar, it removes the record separator from the end of the scalar. If it is presented with an array, it removes the record separator from the end of each scalar in the array.

Manipulating Arrays

Stepping Through an Array

@flavors=qw( chocolate vanilla strawberry mint sherbet );    
for($index=0; $index<@flavors; $index++)
{
print "My favorite flavor is $flavors[$index] and..."
}
print "many others.\n";

The second line does most of the work. $index is initialized to 0 and incremented by 1 until @flavors is reached. Because it is being compared to the scalar $index, @flavors is evaluated in a scalar context, so it evaluates to 5.

foreach $cone (@flavors)
{
print "I'd like a cone of $cone\n";
}

Here, the variable $cone is set to each value in @flavors.


Converting Between Arrays and Scalars

One method to convert a scalar into an array is the split function. The split function takes a pattern and a scalar, uses the pattern to split the scalar apart, and returns a list of the pieces.

@words=split(/ /, "The quick brown fox");
After you run this code, @words contains each of the words The, quick, brown, and fox—without the spaces.

The patterns used by split are actually regular expressions.

@Music=('White Album,Beatles',        
'Graceland,Paul Simon',
'A Boy Named Sue,Goo Goo Dolls'); foreach $record (@Music) { ($record_name, $artist)=split(',', $record); } $numbers=join(',', (1..10));

This example assigns the string 1,2,3,4,5,6,7,8,9,10 to $numbers.


Reordering Your Array

When you're building arrays, often you might want them to come out in a different order than you built them.

For sorting data, Perl provides the sort function. The sort function takes as its argument a list and sorts it in (roughly speaking) alphabetical order; the function then returns a new list in sorted order.

@Chiefs=qw(Clinton Bush Reagan Carter Ford Nixon);
print join(' ', sort @Chiefs), "\n";
print join(' ', @Chiefs), "\n";

The sort function allows you to sort in whatever order you want by using a block of code.

@sorted=sort { return(1) if ($a>$b);               
               return(0) if ($a==$b);               
               return(-1) if ($a<$b); } @numbers; 

The block's task is to return –1, 0, or 1 depending on whether the $a is less than $b, equal to $b, or greater than $b, respectively. The following is an example of the hard way to do a numeric sort, assuming that @numbers is full of numeric values.
Perl has a shortcut: the "spaceship" operator, <=>.

@sorted=sort { $a<=>$b; } @numbers;    

This code is much cleaner, easier to look at, and more straightforward. You should use the spaceship operator only to compare numeric values.

@sorted=sort { $a<=>$b; } @numbers;

To compare alphabetic strings, use the cmp operator, which works exactly the same way.

The final function for this hour is an easy function, reverse. The reverse function, when given a scalar value in a scalar context, reverses the string's characters and returns the reversed string. The call reverse("Perl") in a scalar context, for example, returns lreP.