Arrays of words are easily created
Theqw
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 6The 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] # CurlyArrays can also be accessed from the end by using negative offsets from the end.
$stooges[-1] # IggyReading 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 usescalar
. Some don't.my $stooge_count = scalar @stooges; # 4 my $stooge_count = @stooges; # 4Don'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 http://perl101.org/references.html.
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. 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', );
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.
Modify arrays in-place with 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 @bNow 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 wantedLet'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
.
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)); # 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' )
Select items out of an array with 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;
No comments:
Post a Comment