Lesson 6 - Arrays (Lists)
Summary:

What are arrays/lists?
How can I use them?
How can I manipulate their contents?

As mentioned in the Variables lesson, arrays are structures composed of
a list of scalars. The scalars in the array (called elements) are accessed by
their position in the array. Because of this, arrays are generally best used
for data that has a specific order. There are several Perl functions that can
be used to manipulate arrays, but first, we'll talk about how to create an
array. Note: For the purposes of this lesson, the terms 'array' and 'list' will
be used interchangably, except where specifically defined.

Creating an Array

Array names start with `@`, as in @my_list. Generally, data in round
brackets denotes a list context. The simplest example of this is creating an
array by definition:

@list_of_things = ('table', 'chair', 'Nate', 'screwdriver');

Each element in the array looks much the same as it would if you were
defining it as an individual scalar. The elements in a definition must be
separated by commas. As with scalars, numerical elements do not require quotes
though they still need to be comma-separated. Because of dynamic typing,
arrays can contain both numeric (integer and floating-point) and strings at
the same time.


Accessing Elements in an Array


Elements in an array are accessed by their subscript. This is a number
indicating their position in the array. Contrary to what you might think, the
subscript number for the first element is not 1. Numbering in programming
languages tends to start with 0, and this is true for array subscripts. To
access the first element, use the name of the array, but with a `$` instead of
a `@` to indicate that you want a scalar and not the whole array, and followed
by a number in square brackets indicating which subscript. Example:

@list_of_things = ('table', 'chair', 'Nate', 'screwdriver');
print $list_of_things[2] . "\n"; # prints Nate, *not* chair.
print $list_of_things[0] . "\n"; # prints table

You can change elements in the array much the same way. Example:

@list_of_things = ('table', 'chair', 'Nate', 'screwdriver');
$list_of_things[2] = 'Lacey';
# @list_of_things is now ('table', 'chair', 'Lacey', 'screwdriver')

To access with multiple elements of an array at the same time, e.g. to
replace three sequential elements, specify the beginning and ending subscripts
separated by `..` in the square brackets, and use '@' instead of '$'. Example:

@colors = ('red', 'blue', 'green', 'cyan', 'magenta', 'yellow');
@colors[1..3] = ('orange', 'pink', 'black');
# @colors is now ('red', 'orange', 'pink', 'black', 'magenta', 'yellow')

Incidentally, to get the index of the highest subscript of the array,
use `$#array_name`. This is also the number of elements in the list minus one,
because the numbering starts at zero.


The `pop` and `push` Functions

The first pair of special functions for manipulating arrays is designed
for working on the tail end of the array, i.e. the end with the highest
subscript. `push` adds an element to the end of the array, and `pop` takes one
off. `pop` returns the value of the element that was removed. Example:

@things = ('telephone', 'fax machine', 'printer');
push (@things, 'pencil sharpener');
# @things is now ('telephone', 'fax machine', 'printer', 'pencil sharpener')
$last_thing = pop(@things);
# @things is now back to ('telephone', 'fax machine', 'printer'), but
# $last_thing now contains 'pencil sharpener'.


The `shift` and `unshift` functions

The second pair of array functions, `shift' and `unshift`, are much
like pop and push but work instead on the [0] end of the array. `shift` works
like pop, removing and returning the first element and decrementing the
subscripts of all the other elements. `unshift` works like push, adding an
element and increasing all other subscripts. Example:

-------------------------------------
@things = ('telephone', 'fax machine', 'printer');
$first_thing = shift (@things);
push (@things, $first_thing); # we've rotated the first element down to the
# end of the list
push (@things, shift(@things)); # a quicker way of doing the same thing
unshift (@things, 'keyboard');
# @things is now ('keyboard', 'printer', 'telephone', 'fax machine')

-------------------------------------


The `splice` Function

`splice` is used for adding or removing elements that aren't on the
outside edges of a list. Whereas `push` takes two arguments (the array and the
data to add), and `pop` takes one argument (the array to pop from), `splice`
can take up to four arguments: the array to work on, the offset (number of the
subscript) to start working at, the number of elements to remove (starting at
the offset), and a list of elements to replace the removed elements with. Only
the first two arguments are required. If the number of elements to remove is
unspecified, then it will remove all elements from the offset to the end of the
list. `splice` returns all elements removed, if any (like pop). This sounds
quite complex, but it's fairly simple in practice. Examples:

-------------------------------------
@names = ('Steve', 'Bill', 'Patrick', 'Jill', 'Melanie', 'Mark');
splice (@names, 4); # Crops @names down to the first four elements (remove
# from subscript four onward).
splice (@names, 2, 0, 'Jeff'); # Inserts 'Jeff' at subscript two. 'Patrick'
# and 'Jill' get moved up. Nothing was removed
# because the third parameter was 0.
splice (@names, 0, 1); # A long way of doing shift(@names); remove the element
# from the head of the array.
splice (@names, $#names); # ... and a long way of doing pop(@names).

-------------------------------------

Note the last two examples: They demonstrate a principle reflected
throughout the Perl language, namely, "There's more than one way to do it." For
most problems solvable with Perl, there's at least two ways to implement it.
Here, we demonstrated how to accomplish the work done by `shift` and `pop`
without having to use the functions themselves. How to duplicate `unshift` and
`push` is left as an exercise for the reader.

To conclude the section on arrays, we'll look at a short program that displays a
random string from an array. It uses three functions we haven't looked at
before: `srand`, which seeds the random number generator (to produce more randomness);
`rand`, which returns a random floating-point number between 0 and 1; and `int`,
which trims the decimal portion off its argument.

Get This Sample

#!/usr/bin/perl

# First, seed the random number generator.
srand();

# Define a list of strings to return.
@strings = (
'Perl gives you several ways to do anything, so consider picking the most readable one.',
'Given sufficient time, what you put off doing today will get done by itself.',
'The goal of science is to build better mousetraps.The goal of nature is to build better mice.',
'He that would govern others, first should be the master of himself.',
'After the game the king and the pawn go in the same box.',
'Two is not equal to three, even for large values of two.'
)
# Remember that whitespace is ignored, so this is equivalent to putting all the
# elements on the same line. This way is more readable and easy to change.

$randomElement = int((rand+0.5)*$#strings);
# This picks a random element by getting a random number from 0 to 1,
# multiplying it by the index of the highest subscript, and then rounding
# it down. The 0.5 added to the original random number is to
# compensate for the fact that int() doesn't know how to round up.

# Print out 'Quote of the Day' followed by the element of the array picked by
# the randomizer.
print "Quote of the Day:\n$strings[$randomElement]\n";

Lesson 6a - Hashes

Home | Lessons | Get Perl | Resources