Perl

02. Arrays and Lists


Lists and Arrays

Lists of data (1, 2, 3) and arrays are related in Perl.

Ordered sequences of scalar values.


Lists

Lists aren't a specific type of data like a scalar or array, just a way of talking about a group of ordered elements in your code.

(1, 2, 3, 4) = list of scalar data elements.

(1, "Greg", 3.4, -9.4) = list of scalar data elements.

() = empty list.

(1 .. 5) == (1, 2, 3, 4, 5), shorthand for a range.


Arrays

Arrays are the second major data type in Perl.

Prefixed by the at-sign (@) when referring to the array as a whole, prefixed by $ when referring to a single element.

Arrays are not limited to a predefined length, grow or shrink as necessary.

Arrays not limited to an upper size limit, will suck up all your memory if desired.

We can have an array "greg" and a scalar "greg", no conflict to perl.

@array_one = (1, 2, 3);        # creates array of three elements

print $array_one[1];           # prints "2" (zero-based indexing)
print @array_one;              # prints "123"
print "@array_one";            # prints "1 2 3", quotes make spaces
print @array_one[1,2];         # prints "23", an array slice, a list

print @array[1];               # perl -w gives warning: better as $array[1]

@a = @b;                       # array copy

@a = (1, @b, 4);               # a now has 1 at start, 4 at end,
                               #  and elements of b in between

@bloop = (1, 2, 3);
$bloop[3] = 7;                 # bloop now: (1, 2, 3, 7)
$bloop[5] = 9;                 # bloop now: (1, 2, 3, undef, 9)

Array Size:

@array = (3, 5, 6);

$len = @array;        # array now in scalar context, returns current length
print $len;           # prints "3"

$last = $#array;      # or use special: $#array, returns last index, or len - 1
print $last;          # prints "2"

Weirder

Lists can be lvalue!

($first, @rest) = @values;    # first element to first, rest to rest

($one, $two) = ($two, $one);  # swap, no explicit temp value

($x, $y) = @a;                # grab first two values

($x, @b, $y) = @a;            # x gets first, b gets rest, y undef
Other Indexing tricks:
print (7,8,9)[1];             # print out "8"

@b = @a[1 .. 3];              # copy elements 1 through 3
@b = @a[1 .. 3, 4, 6];        # copy elements 1 through 3, 4 and 6

Can index from other end

print $array[-1], $array[-2];    # print last element and 2nd-to-last

Context

Many perl operations occur differently in different "context", scalar or list context.

chop $line;           # will chop the value in scalar line.

chop @lines;          # will chop all values in array line.

@lines = <STDIN>;     # read all lines from stdin, put in array

scalar function forces scalar context of an item.

localtime behavior:

#!/usr/local/bin/perl -w

$time = time;        # get seconds since epoch

# scalar context, prints out for humans
print "time (scalar) = ", scalar(localtime($time)), "\n";

# list context, returns list of time elements
@times = localtime($time);
print "time (list) = @times\n";

# list context also
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);

($year) = (localtime(time))[5];   # year is actual year minus 1900
                                  # add 1900 to this value
print "year is ", ($year + 1900), "\n";

output: (minus unused vars warnings)
time (scalar) = Sun Sep 26 14:33:27 1999
time (list) = 27 33 14 26 8 99 0 268 1
year is 1999

Array Functions

push/pop - treat array as stack, play with right side of it

@data = (1, 2, 3);

push(@data, 4);        # data now (1, 2, 3, 4)
@data = (@data, 5);    # data now (1, 2, 3, 4, 5) (same thing)

$last = pop(@data);    # last now 5, data now (1, 2, 3, 4)

pop returns "undef" if no more data.

shift/unshift - treat array as stack, play with left side of it

@values = qw(a b c);        # like @values = ("a", "b", "c")

$first = shift(@values);    # first now "a", values now ("b", "c")

unshift(@values, "n");      # values now ("n", "b", "c");

splice - inserts a list into another, removing some elements if desired.

Specify: list to be operated on, index to start deleting at, length of deletion (how many elements), new list elements.

#!/usr/local/bin/perl -w

@a = (1, 2, 3, 4);
print "a now: @a\n";

splice(@a, 1, 1, "b");
print "a now: @a\n";

splice(@a, @a, 0, 5, 6);
print "a now: @a\n";

@b = (7, 8);
splice(@a, $#a + 1, 0, @b);
print "a now: @a\n";

output:

a now: 1 2 3 4
a now: 1 b 3 4
a now: 1 b 3 4 5 6
a now: 1 b 3 4 5 6 7 8

If you omit the list to insert, it just deletes. If you omit the length to delete, it will delete the rest.

reverse - return list in reverse order

Works on a copy of the list
@a = reverse(@b);

@a = reverse(7, 8, 9);      # a now (9, 8, 7)

@a = reverse(@a);           # reverse self

sort - sort list as ASCII strings, takes list as arg like reverse, more on sort later.

print - note how "print" function can take a list of items to print.

print "hi";

print "hi", " ", "there", "\n";        # print 4 elements

print "hi" . " " . "there" . "\n";     # one element

ARGV

Your command line args are put into an array, @ARGV.

print $ARGV[0];        # spits out first argument to your script

print $#ARGV;          # prints number of args minus 1 (zero-based)

if (@ARGV) {
   print "we got arguments\n";
}

if (@ARGV == 2) {
   print "we got TWO arguments\n";
}

foreach $file (@ARGV) {
   print "working on file $file\n";
}

shift works on ARGV by default, pulling off the first argument.

$pattern = shift(@ARGV);      # same thing
$pattern = shift;

$0 holds name of script.