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
|