Arrays & Lists
Arrays of words are easily created
The qw operator makes creating arrays easy.
It means "quote on whitespace into a list":
my @stooges = qw( Larry Curly Moe Iggy );
my @stooges = qw(
Larry
Curly
Moe
Iggy
);
The elements do not interpolate, so:
my @array = qw( $100,000 );
The single element of @array is '$100,000'.
Access arrays with numeric values
To get a single scalar out of an array, access it with the [] and a $ sigil. All arrays in Perl start at 0.
$stooges[1] # Curly
Arrays can also be accessed from the end by using negative offsets from the end.
$stooges[-1] # Iggy
Reading a non-existent element gives undef.
$stooges[47] # undef
The length of an array is its scalar value
Put an array in scalar context to get its length. Some people like to explicitly use scalar. Some don't.
my $stooge_count = scalar @stooges; # 4
my $stooge_count = @stooges; # 4
Don't take the length of an array with length. That gives the length of a string.
my $moe_length = length $stooges[@stooges/2];
length $stooges[2];
length 'Moe';
3;
Arrays have no boundaries
Arrays don't have any finite size, and don't have to be predeclared. Arrays change in size as necessary.
Arrays are also not sparse. This code makes a 10,000-element array.
my @array = ();
$array[10000] = 'x';
@array is now 10,001 elements long (0-10,000), of which only one is populated. The other 10,000 are undef.
Arrays flatten out and do not nest
Unlike PHP, arrays flatten into one big list when combined:
my @sandwich = ( 'PB', 'J' );
my @other_sandwich = ( 'B', 'L', 'T' );
my @ingredients = ( @other_sandwich, @sandwich );
# ( 'B', 'L', 'T', 'PB', 'J' )
This means you can't have an array "contain" another array, or a hash. To do that, you need references.
Lists can have extra commas
One of the greatest features of Perl is the ability to have an extra comma at the end of a list.
my @array = (
'This thing',
'That thing',
);
Then when you add another thing
my @array = (
'This thing',
'That thing',
'The other thing',
);
Use arrays like queues and stacks
shift removes from the beginning of the array:
my $next_customer = shift @customers;
unshift adds to the beginning of an array:
unshift @customers, $line_jumper;
push adds to the end of an array:
push @customers, $dio; # The last in line
pop removes from the end of an array:
my $went_home = pop @customers;
Extract sections of an array with array slices
Array slices are just array accesses with multiple indices.
my @a = 'a'..'z'; # 26 letters
# a, e, i, o, u...
my @vowels = @a[0,4,8,14,20];
# And sometimes "y"
push( @vowels, $a[-2] ) if rand > .5;
Note that when accessing an array slice, the sigil is @, not $, because you're returning an array, not a scalar. A common mistake for beginners is to access an array element with a @ sigil, not $, and get back a slice, which is a list:
# WRONG: Returns a 1-element list, or 1 in scalar context
my $z = @a[-1];
# RIGHT: Returns a single scalar element
my $z = $a[-1];
Assign chunks of an array with array slices
You can have array slices as lvalues, or values on the left side of the equals sign that can be assigned to.
# Replace vowels with uppercase versions
@a[0,4,8,14,20] = qw( A E I O U );
# Swap first and last elements
@a[0,-1] = @a[-1,0];
Note that the left and right slices must be of the same size. Any missing values on the right side of the equals sign will be replaced with undef.
splice XXX
Explain splice XXX
Process arrays easily with map
map is essentially a foreach loop that returns a list.
You can use it to convert an array into a hash:
my @array = ( 1, 2, 3, 4, 5 );
my %hash = map { $_ => $_ * 9 } @array;
# %hash = ( 1 => 9, 2 => 18, 3 => 27, 4 => 36, 5 => 45 )
or to transform a list:
my @array = ( 'ReD', 'bLue', 'GrEEN' );
my @fixed_array = map(ucfirst, map(lc, @array));
# @fixed_array = ( 'Red', 'Blue', 'Green' )
Watch out, though: If you modify $_, you will modify the source data. This means the above might be changed to:
my @array = ( 'ReD', 'bLue', 'GrEEN' );
map { $_ = ucfirst lc $_ } @array;
# @array = ( 'Red', 'Blue', 'Green' )
if you don't care about @array.
Select items out of an array with grep
grep is essentially a foreach loop that returns a list, but unlike map, will only return elements that cause the condition to return true.
my @array = ( 0, 1, 2, 3, 4, 5 );
my @new_array = grep { $_ * 9 } @array;
# @new_array = ( 1, 2, 3, 4, 5 );
It will modify the source data the same way as map, however:
my @array = ( 0, 1, 2, 3, 4, 5 );
my @new_array = grep { $_ *= 9 } @array;
# @array = ( 0, 9, 18, 27, 36, 45 );
# @new_array = ( 9, 18, 27, 36, 45 );
XXX Put an example about regexes
