18 Part 16: Array Functions

LinuxChix Perl Course Part 16: Array Functions

1) Introduction
2) Re-Visiting Old Perl Functions
3) Six Simple Functions
4) Consider the Context
5) Exercise
6) Answers to Previous Exercises
7) Past Information
8) Credits
9) Licensing

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

1) Introduction

Perl includes many functions that make handling arrays a breeze.

Some of these functions are quite versatile, i.e., you can change the
way they work if you need a slightly different behaviour. We could never
get through all the different customisations that can be done, but you
can find out more about any one of these functions by typing
"perldoc -f <function name>" at the command-line.

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

2) Re-Visiting Old Perl Functions

Some Perl functions that we've already seen will accept either scalars
or lists. For example, we've seen the "chomp" function used with
scalars, but it can also be used with a list (in which case it chomps
every element of the list):

chomp($scalar);
chomp(@array);
chomp($a, $list, $of, $scalars);

But not all Perl functions can do this. For example, the "uc" function
capitalises all the letters in a string, but it won't accept a list.
Always RTFM to make sure.

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

3) Six Simple Functions

We're going to start with

a) split - splits a string into an array
b) join - combines an array to form a string
c) reverse - reverses the order of an array (first element becomes last)
d) sort - puts the array in alphabetical order (NOT numerical order)
e) push - adds one or more values to the end of an array
f) pop - removes and returns the last element of an array

Examples:

my @arr = split( /[#!]+/, 'foo###bar!!!baz' );
# Now @arr = ('foo', 'bar', 'baz')
print join('**', @arr); # Output is: "foo**bar**baz"
@arr = reverse(@arr); # Now @arr = ('baz', 'bar', 'foo')
@arr = sort(@arr); # Now @arr = ('bar', 'baz', 'foo')
my $x = pop(@arr); # Now $x='baz' and @arr=('foo', 'bar')
push(@arr, 'Bob', 'Jane'); # Now: ('foo', 'bar', 'Bob', 'Jane')

Note that only the functions "push" and "pop" change the array variable
passed in. This means that the other functions can take any list, not
just an array:

my @arr = ('foo', 'bar', 'baz');
print join('**', @arr); # Output is: "foo**bar**baz"
print join('**', 'foo', 'bar', 'baz'); # Same as previous line
print join('**', 'A', @arr, 'B'); # Output: "A**foo**bar**baz**B"

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

4) Consider the Context

Many Perl functions and operators behave differently depending on the
"context". Perl has three possible contexts: scalar context, list
context and void context:

my @arr = ('foo', 'bar', 'baz');
my @a = reverse(@arr); # Array context
my $s = reverse(@arr); # Scalar context
reverse(@arr); # Void context

print "@a\n"; # Output is: baz bar foo
print "$s\n"; # Output is: zabraboof (foobarbaz backwards)

Note that the context is determined by how the return value is used, NOT
the parameters passed to the function/operator. This is quite Perl-like;
most languages have functions that always return the same value, no
matter how it's used.

The use of an array (variable) in scalar context returns the length of
the array:

my @array = ('foo', 'bar', 'baz');
my $scalar = @array;
print "$scalar\n"; # Output is 3.

But don't try this with a literal list:

my $scalar = ('foo', 'bar', 'baz'); # Warnings generated here.
print "$scalar\n"; # Output is baz.

In the above cases the context was obvious because we assigned to an
array or scalar variable. But the context can also be indicated by an
operator. For example, arithmetic operators are all scalar, as is string
concatenation:

print "The length of the array is: " . @array . "\n";

We can also force scalar context by using the "scalar" operator:

($length_a, $length_b) = (scalar @a, scalar @b);

"man perlfunc" tells us: "There is no equivalent operator to force an
expression to be interpolated in list context because in practice, this
is never needed."

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

5) Exercise

Write a Perl program that reads /etc/passwd and outputs just a list of
usernames and UIDs, ordered alphabetically by username. Remember: There
Is More Than One Way To Do It.

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

6) Answers to Previous Exercises

a) Here is a tail program that works on even a small number of lines.

#!/usr/bin/perl -w
use strict;

my @lines = <>;

my $lines_to_output = @lines; # Get number of lines.
$lines_to_output = 10 if $lines_to_output > 10; # Limit number of lines.

print @lines[ -$lines_to_output .. -1 ];

b) Here is a reversal algorithm.

#!/usr/bin/perl -w
use strict;

my @array = qw/A B C D E F G/;

my @result;
foreach my $element (@array) {
@result = ($element, @result);
}

print "Result is: @result\n";

As you might guess, it would be a little more efficient to use "push"
and "pop", but we hadn't seen these functions last week. (Calling the
"reverse" function would be more efficient still! :-)

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

7) Past Information

Part 1: Getting Started
http://linuxchix.org/pipermail/courses/2003-March/001147.html

Part 2: Scalar Data
http://linuxchix.org/pipermail/courses/2003-March/001153.html

Part 3: User Input
http://linuxchix.org/pipermail/courses/2003-April/001170.html

Part 4: Control Structures
http://linuxchix.org/pipermail/courses/2003-April/001184.html

Part 4.5, a review with a little new information at the end:
http://linuxchix.org/pipermail/courses/2003-July/001297.html

Part 5: The "tr///" Operator
http://linuxchix.org/pipermail/courses/2003-July/001302.html

Part 6: The "m//" Operator
http://linuxchix.org/pipermail/courses/2003-August/001305.html

Part 7: More About "m//"
http://linuxchix.org/pipermail/courses/2003-August/001322.html

Part 8: The "s///" Operator
http://linuxchix.org/pipermail/courses/2003-August/001330.html

Part 9: Simple File Access
http://linuxchix.org/pipermail/courses/2003-September/001340.html

Part 10: Executing Commands with "open"
http://linuxchix.org/pipermail/courses/2003-September/001344.html

Part 11: Perl Variables
http://linuxchix.org/pipermail/courses/2003-October/001345.html

Part 12: Side Effects with Perl Variables
http://linuxchix.org/pipermail/courses/2003-October/001347.html

Part 13: Perl Style
http://linuxchix.org/pipermail/courses/2003-October/001349.html

Part 14: Arrays
http://linuxchix.org/pipermail/courses/2003-October/001350.html

Part 15: More About Lists
http://linuxchix.org/pipermail/courses/2003-November/001351.html

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

8) Credits

Works cited: man perlfunc

Thanks to Jacinta Richardson for fact checking.

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

9) Licensing

This course (i.e., all parts of it) is copyright 2003 by Alice Wood and
Dan Richter, and is released under the same license as Perl itself
(Artistic License or GPL, your choice). This is the license of choice to
make it easy for other people to integrate your Perl code/documentation
into their own projects. It is not generally used in projects unrelated
to Perl.