The qw
operator makes creating arrays easy.
It means "quote on whitespace into a list":
# Perl 5 my @stooges = qw( Larry Curly Moe Iggy ); # or my @stooges = qw( Larry Curly Moe Iggy );
In Perl 6, the qw
is simplified:
my @stooges = < Larry Curly Moe Iggy >; # or my @stooges = < Larry Curly Moe Iggy >;
The elements do not interpolate, so:
my @array = qw( $100,000 ); # Perl 5 my @array = < $100,000 >; # Perl 6
The single element of @array
is '$100,000'.
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
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 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
.
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 http://perl101.org/references.html.
One of the greatest features of Perl is the ability to have an extra comma at the end of a list. For example:
my @array = ( 'This thing', 'That thing', );
This makes adding or deleting items super easy when you edit your code, since you don't have to treat the last as a special case:
my @array = ( 'This thing', 'That thing', 'The other thing', );
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;
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];
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
splice
lets you splice arrays into other arrays. Let's look at a few common ways of doing it wrong that should illustrate its usefulness:
my @a = qw(Steve Stu Stan); $a[1] = ['Stewart', 'Zane']; # @a = ('Steve', ARRAY(0x841214c), 'Stan') # Memory address to an array reference my @a = qw(Steve Stu Stan); my @b = qw(Stewart Zane); $a[1] = @b; # @a = ('Steve', 2, 'Stan') # Returns a scalar reference, the length of @b
Now let's use splice
:
@a = qw(Steve Stu Stan); splice @a, 1, 1, 'Stewart', 'Zane'; # @a = ('Steve', 'Stewart', 'Zane', 'Stan') # This is just what we wanted
Let's break down the argument list for splice
: first, we name the array we're operating on (@a
); second, we define the offset (how far into the list we want the splice to start); third, we specify the length of the splice (how far forward from the offset we'll be deleting to make room for the new list); finally, we list the items we want inserted.
If all else fails, perldoc -f splice
.
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)); # note the nested 'map' functions # @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' )
grep
grep
is essentially a foreach loop that returns a list, but unlike map
, it 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 );
We can also pass regular expressions into grep
; in this example, we want only people with the surname 'Doe' put into our new array:
my @people = ( 'John Doe', 'Jane Doe', 'Joe Sixpack', 'John Q. Public', ); my @does = grep { $_ =~ /\bDoe$/ } @people; # @does = ('John Doe', 'Jane Doe');
or even shorter
my @does = grep { /\bDoe$/ } @people;
Submit a PR to github.com/petdance/perl101
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.