Prev | Up | Contents | Down | Next

3.3. Operations on Arrays

From the point of view of a typical University data structure course an array is a data type that contains or stores numbered items sequentially in memory. Each numbered item is called an element of the array, and the number assigned this element is called its index.

In compiled languages typically all elements of array should have the same type (and thus the size in bytes). In this case index is mapped to memory addresses and an increment of the index is the size of the element in bytes. 

But Perl arrays are a different and are more common to lists than to arrays in languages like C or Pascal.  First because Perl is an untyped language, an element of an array may be of any type, and different elements of the same array may be of different types. Array elements may even contain pointers to other arrays, which allows you to create data structures commonly called "array of arrays."

The second feature of Perl arrays is that they are sparse. This means that array indexes need not fall into a contiguous range of numbers, and that memory is allocated only for those array elements that are actually stored in the array. They are more like an index in the database, or filenames in a directory. Thus, when you assign values only to the first and, say, 1000th elements of an array, Perl will allocate memory only for two elements, not for 1000 elements.

As we already mentioned, it's very important to understand that Perl arrays should be considered not as arrays in compiled languages like Fortran and C, but as an attempt to introduce a concept of programmable editor buffer (with indexes as line number) into the programming language. From another point of view of data structures Perl arrays are close to a file directory with indexes representing file names and to the database of records with numeric key. We will use the terms list and array more or less interchangeably, but there is a small difference between them that we will discuss later.

Perl arrays should be considered not as arrays per se, but as an attempt to introduce a concept of programmable editor buffer into the scripting language:
indexes are just line numbers in this buffer

Anyway, like in other languages arrays allow to access to their elements by a integer number (index) and like in C the first element of array has index zero. For example the first element of array @week is $week[0], the second element is $week[1], and so on. Again Perl arrays looks similar to data structures used in sed, vi and other text editors. In Perl we can even count elements from the other end of the array using negative indexes. For example the last element of the array @week is always $week[-1], element before it is $week[-2] and so on.

Negative indexes are used quite ingeniously in Perl -- as a way of calculating index in the reverse direction. The last element of the array @week is $week[-1], the element before last is $week[-2], etc. This is quite convenient shortcut worth remembering.

Being actually lists, arrays in Perl have no lower or upper bound and can accept any type of variable (both numbers and strings). All array names are prefixed by an @  symbol (but elements should be prefixed with $ -- the important nuance we already discussed). For example:

@workweek  = ("Mn", "Ts", "Wn", "Th","Fr"); # initialization of array @workweek with 5 values
@weekend = ("St", "Sn"); # another array with just two elements
@day_array = ($day); # an array with just one element

Please note the difference: @day_array is an array with one element. Variable $day is a scalar. List notation for arrays can be used whenever you can use an array in Perl. Important case is its use of the left side of the assignment statements that we will discuss next.

Index brackets in Perl enforce conversion to numeric, so $workweek["Mn"] is essentially equal to $workweek[0] .  Similarly $workweek["Ts"] is also equivalent to $workweek[0]

The last element of array $workweek has index $#workweek. It also can be accessed as $worksweek[-1].

Note: array can contain empty or undef elements. So the index of the last element does not guarantee that all elements exists. It is just a number that is one equal to the maximum index ever used -- it does not tell you how many actual elements are present. Total number of slots in the array is one more than the index of the last element. To get it you can assign an array to a scalar variable or use the built-in function scalar.

$days_in_a_week = $#week+1; # will assign the index of the last element incremented by one
$days_in_a_week = scalar(@week); # same thing

Quotes will turns the list into a string with a space between each element. So they act as an implicit call to the join function, not to the scalar function as you might expect:

$f = "@week"; # result is the sting that contains all elements of @week with delimiter
#dependent of the value of $" -- default delimiter(usually blank)

Arrays and Lists, Arrays Initialization

Lists in Perl is a notation very similar to arrays. List should be included in parenthesis and should contain zero or more (usually scalar) values separated by comma, for example ("Mn", "Ts", "Wn", "Th", "Fr"). Lists can be assigned to arrays and vise versa (see below). That significantly increase power and flexibility of the language.

Actually list notation for arrays has one difference with an array notation: in a scalar context, array returns the length of the array, but list returns the last value (like the C comma operator), for example.

$last_day = ("Mn", "Ts", "Wn", "Th", "Fr"); # $last_day will be assigned the value "Fr"

List assignment also can be used to assign initial values to several related scalar variables, for example:

($day, $month, $year)=(10,2,2000);

In case of integer arrays, they can be initialized with so called "ranges", for example:


Range operator is more capable that demonstrated in this simple example (Adapted from The Range Operator (..))

The range operator is used as a shorthand way to generate arrays. It simplifies the process of creating arrays with contiguous sequences of numbers and letters. We'll start with an array of the numbers one through ten. For example, if we need to create an array with ten elements that include 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10 simply write:

@array = (1..10);

You can also create an array of contiguous letters, for ecample: an array with ten elements that include A, B, C, D, E, F, G, H, I , and J. is written

@array = ("A".."J");

And, of course, you can have other things in the array definition besides the range operator.

You can create an array that includes AAA, 1, 2, 3, 4, 5, A, B, C, D, and ZZZ by the following

@array = ("AAA", 1..5, "A".."D", "ZZZ");

You can use the range operator to create a list with zero-filled numbers.

To create an array with ten elements that include the strings 01, 02, 03, 04, 05, 06, 07, 08, 09, and 10 do:

@array = ("01".."10");

You can use variables as operands for the range operator. To assign a string literal to $firstVar. Create an array with ten elements that include the strings 01, 02, 03, 04, 05, 06, 07, 08, 09, and 10:

$firstVar = "10";
@array = ("01"..$firstVar);

If you use strings of more than one character as operands, the range operator will increment the rightmost character by one and perform the appropriate carry operation when the number 9 or letter z is reached. You'll probably need to see some examples before this makes sense.

You've already seen "A".."Z," which is pretty simple to understand. Perl counts down the alphabet until Z is reached.

Caution should be heeded however: The two ranges "A".."Z" and "a".."Z" are not identical. And the second range does not contain all lowercase letters and all uppercase letters. Instead, Perl creates an array that contains just the lowercase letters. Apparently, when Perl reaches the end of the alphabet-whether lowercase or uppercase-the incrementing stops.

What happens when a two-character string is used as an operand for the range operator? To create an array that includes the strings aa, ab, ac, ad, ae, and af. write:

@array = ("aa" .. "af");

This behaves as you'd expect, incrementing along the alphabet until the f letter is reached. However, if you change the first character of one of the operands, watch what happens.

If we create an array that includes the strings ay, az, ba, bb, bc, bd, be, and bf. we must write:

@array = ("ay" .. "bf");

When the second character is incremented to z, then the first character is incremented to b and the second character is set to a.

Note If the right side of the range operator is greater than the left side, an empty array is created.

Array operations, push/pop, shift/unshift pairs of built-in functions

Perl provide a set of array operations very similar to PL/1 operations. One unpleasant problem is that the set of array operations is completly different from the set of operations of strings. That's regrettable and complicates the language.

Array to array assignments

As arrays are actually a text editor buffer Perl provide a pretty rich functionality somewhat similar to the functionality of programmable editors like Sed. First of all you can copy one array to another by simple assignment

@week=@workweek; # buffer to buffer (Select all) copy

What is important that on both sides of the assignment statement one can also use list notation. This way arrays can be used to make multiple assignments to scalar variables and vise versa. This is a very flexible and powerful feature that can be used for transposition of elements, extracting elements from array, etc. For example:

($a, $b) = ($b, $a);	# Transposition of $a and  $b. It works...
($a, $b) = @week;	# $a and $b are the first two elements of @week.

Splice built-in function

Function splice is very similar to substr and as such is probably the easiest of all array functions to remember and use. It has four forms equivalent to four forms of substr

  2. splice ARRAY,OFFSET
  3. splice ARRAY

But semantic unfortunately is different. Unlike substr splice(ARRAY,OFFSET,LENGTH) removes the elements designated by OFFSET and LENGTH from an array.  so this is a function that changes tha value of its first argument.

In list context, it returns the elements removed from the array. In scalar context, returns the last element removed, or undef if no elements are removed.

If OFFSET is negative then it starts that far from the end of the array. If LENGTH is omitted, removes everything from OFFSET onward. If LENGTH is negative, removes the elements from OFFSET onward except for -LENGTH elements at the end of the array. If both OFFSET and LENGTH are omitted, removes everything. If OFFSET is past the end of the array, Perl issues a warning, and splices at the end of the array.

You can also use ranges to generate subset of array.

Built-in function push

The push operation make it possible to concatenates arrays with scalars or with arrays. The push build-in function does exactly this:

push(@week, "St", "Sn"); # can add element only to the end (concatenate)

Here is another example when we concatenate two arrays using push:

push(@week, @weekend); # same effect as above

Please not  that push modifies the first argument (which should be an array). It does not return a new array as the result. This is yet another Perl idiosyncrasy. 

If you want to prepend the  array you should use  function unshift.

The opposite to the push function is function pop It is an analog of chop function used for strings (but due to, probably questionable decision to permit usage of chop with arrays with different semantic one needs a new name -- here one can see that the possibility to simplify the language by extending semantic of string functions on arrays was missed and this definitely overcomplicates the language).

Built-in function pop

The function pop  removes the last item from a list and return it . Please note that the array size will be truncated by one.

$holiday = pop(@week);	# Now $holiday will contain "Sn"

Built-in function pop is extracting the same element as $ARRAY[$#ARRAY].

It is also equivalent to


If there are no elements in the array, pop returns the undefined value (although this may happen at other times as well). If ARRAY is omitted, pop performs operation on the @ARGV  array in the main program, and the @_  array in subroutines, just like shift.

Built-in function shift

We usually process the array from the beginning and in this case shift function is more convenient than pop. It removes the first element of an array, and return it

shift @week;

The shift function returns the first element of the array and remove it, shortening the array by one. If there are no elements in the array, shift returns the value undef.

Built-in function unshift

The opposite function unshift will add the list supplied as the second argument to the  array supplied as the first:

Searching for the element

There is no built-in function for this operation in Perl before 5.10. Perl 5.10+ contains the 'smart-match' operator ~~, which returns true if a certain element is contained in an array or hash, and false if it doesn't (see perlfaq4). Please be aware that the smart match feature is experimental. For example:

use strict;
use warnings;
use 5.010;

my @array  = qw/aaa bbb/;
my $wanted = 'aAa';

say "'$wanted' matches!" if /$wanted/i ~~ @array;   # Prints "'aAa' matches!"

Unlike Python in. If you want to find  the first match  you can use function first from List::Util which is a standard module included in  all Perl distributions. For example

use List::Util 'first';
my $match = first { /pattern/ } @strings

The only useful idiom for searching element if you need to find all positions of a given element is slightly perverted usage of grep function:


use strict;
use warnings;

my @x = ( 1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1 );
my @i = grep { $x[$_] == 3 } 0 .. $#x;
print "@i\n";

You can can also use firstidx function from List::MoreUtils which needs to be installed from CPAN:

use strict;
use warnings;
use List::MoreUtils qw(firstidx);

my @nums = ( '830974', '722065', '722046', '716963' );
printf "item with index %i in list is 722065\n", firstidx { $_ eq '722065' } @nums;

item with index 1 in list is 722065
If you will be doing many searches of the array, AND matching always is defined as string equivalence, then you can normalize your data and use a hash.
my @strings = qw( aAa Bbb cCC DDD eee );

my %string_lut;

# Init via slice:
@string_lut{ map uc, @strings } = ();

# or use a for loop:
#    for my $string ( @strings ) {
#        $string_lut{ uc($string) } = undef;
#    }

#Look for a string:

my $search = 'AAa';

print "'$string' ", 
    ( exists $string_lut{ uc $string ? "IS" : "is NOT" ),
    " in the array\n";

Let me emphasize that doing a hash lookup is good if you are planning on doing many lookups on the array. Also, it will only work if matching means that $foo eq $bar, or other requirements that can be met through normalization (like case insensitivity).

See also

How do I search a Perl array for a matching string - Stack Overflow

Conversions between Strings and Array (split and unpack functions)

The function split can be classified as string function, as array function and as the function that can use a regular expression, but we will discuss it as a string function. The function generally accept two arguments: delimiter (which is a regular expression, but we will limit ourselves to strings right now) and target string. For example in Unix colon is a pretty common delimiter for configuration files and we can get elements from the line using split function:


Target string or both arguments can be omitted so if $_ contain required string we can write @pass_elems=split(':'). Or if we plan to split on whitespace @pass_lelem=split; At the same time Perl does not understand the notation split(,pass_line); which have a clear semantic meaning -- default delimiter is used. Another similar example:

$_ = "Nick,Tanya,Sergey";
@family = split(','); # equal to split(',',$_)

which has the same overall effect as

@family = ("Nick", "Tanya", "Sergey");

The default delimiter is whitespace (set of characters that includes blank, tab and newline).

More interesting usage of split is parsing the string into several scalars by using the list notation on the right side of the assignment statement:

$_ = "Nick Tanya Sergey"; # a default variable that split operates upon
# $husband will contain Nick
($husband, $wife, $child)=split; # all three

We will discuss more complex cases of split in the regular expression chapter.

open(passwd,  variable we 
already saw in the try function, and it's another strange Perl creature -- useful 
and dangerous at the same time because you never know what will change this default 
variable as there are no rules in this regard in Perl and everything is decided 
on ad hos basis. If you do not supply argument to split it will 
use $_ as a default argument. All Perl input functions put the current 
line into this variable after reading a record. 

The split function can be conveniently used for conversion from strings to arrays and for parsing simple stream of data with fixed delimiter. Please remember that $_ is a default argument and whitespace is a default delimiter.

($weekend1,$weekend2)=split; # $_ is used as argument and whitespace as a default delimiter
($weekend1)=(split)[0]; # if 'St,Sn' is the string and ',' is
                        # the delimiter then result will be "St"                       
($cur_day, @rest_of_the_week) = @week;	# here the second element is an array

There is an important nuance in using array in the list notation as in the example above -- array assignments are greedy, so you should never put array name anywhere but the last element of the list:

# @new_week will be assigned all elements from @weeks and the variable
# $newday will be left undefined.
(@new_week, $lastday) = @week;	# probably an error

One important shortcut is the ability of split to convert a string into array of characters. In this case zero length string should be used as the first parameter:


We will return to this function in regular expressions chapter, but for now please read man page for the function:

Split up a string using a regexp delimiter


Unpack is probably the second most useful built-in function after splice. Regrettably Perl does not support scanf function from C. Instead it provides similar functionality with unpack. There can be question about introducing a new function instead of tried and true scanf, but again things are already done...

unpack() takes a string and extracts relevant parts of the string into a list, returning an array (in scalar context, it returns the first value produced). Like scanf function in C it uses formatting TEMPLATE. Here I will mention most frequently used formats. See Perl documentation for the complete list:

    A   An ascii string, truncate trailing spaces from the resulting string
    a   An ascii string, do not truncate trailing spaces from the result
    x   A byte that you need to ignore

When unpacking, "A"  strips trailing spaces and nulls, but "a"  does not.

It is interesting to note that one can emulate the substr function with unpack, for example

$word2=substr("Hello world", 6,5); # get the second word
$word2=unpack("A6 A5", "Hello world"); # same thing
If you need to extract several words list on the left side of the assignment statement should be used:
($a,$b)=unpack("a5 x1 a5","Hello world");

The same result can be achieved by using

($a,$b)=unpack("A6 A5","Hello	world"); # A6 will truncate trailing space

Perl permits generating format string for the pack function dynamically. In case scalar variables are used in the format string they will be interpolated -- one can use scalar variables instead of constant length, for example

($a,$b)=unpack("a$i x$j a$k","Hello	world");

Displaying arrays

Yes it is possible to print content of an array in print statement, but user beware. Since context is important, it shouldn't be too surprising that the following all produce different results:

print @week;	# the list will be expanded -- all elements will be printed
print "@week";	# guess what will be printed ?
print @week."";	# Slightly pervert way to enforce a scalar context ;-)

The index of the last element of an array and the number of elements in the array

The way of getting the index of the last element is to use $# prefix, like in the example below:

$last_index = $#array;
The last index is one less that the number of elements as indexes are started with zero:
@array = ('1','2')
$i= $#array  # $i now equals 1 not 2 because it is the index of the last element.
Again I would like to remind that scalar(@array) function provide the number of elements in the array, but prefix $# ( you can consider it to be a function) provides the index of the last element. For example:
for ($i = 0; $i < scalar(@X); 	$i++) {
   print $X[$i];

The index of the last element of array is always one less than the number of elements, expressions ($#arraya+1) and scalar(@array) are always equal.

Actually operator "<" presuppose scalar on both parts (scalar content in Perl speak) so you can write:

for ($i = 0; $i < @X; $i++) {
   print $X[$i];

This is how loops are usually are written in Perl -- you will see that almost nobody use the scalar function.

The scalar built-in function convert its argument into a scalar. Return variable can be not that intuitive -- for example a scalar value of an array is the number of its elements, but never mind.

Again, if the scalar function is supplied with an array argument it returns the number of elements in an array. It just isn't the semantic you would like to expect, but that's how it is. For example:

@X = (1,2,3,4);
$X_size = scalar(@X);
print $X_size; # will print the number '4'.

Actually the scalar function is seldom used. For all operations that expect scalar arguments conversion will be performed automatically and you do not need specify function explicitly. For example:

$number_of_elements = @X; # @X in a scalar context

Grep and Map

There are two related functions in Perl grep that resembles Unix grep and map. Both are essentially an shorthand for the foreach loop. Their main value is not a new functionality, but the ability to make the code more compact. Both functions accept two arguments: the first is an expression and the second is the list or array. Both are shorthand for foreach look.

The main difference between them is that grep can just select certain elements from the array or list while map can transform them into a new area.

See also

Other Important Build-in Functions


The function sort allows you to sort an array using your own comparison routine. For example:

sort (@array);
sort { expression } @array);
sort sort_function @array;

The default usage of sort is to sort in alphanumeric order. If you wish to to sort the list numerically you might use:

@array Name = sort ($a<=>$b) @array Name; # numeric sort

In this case expression is $a<=>$b is used as comparison function for sort. The sort function should use the special values $a and $b (to denote elements that we compare) and after expression is evaluated should provide just three value -1, 0 or +1. The value of expression is passed to the sorting subroutine.

You can use a function call in place of expression, so sorting can be quite flexible and use for comparison only certain fields instead of all strings $a and $b.


Like in strings this function takes an array, and reverse the order of elements. For example is we have

@week = ("Mn","Ts","Wn","Th","Fr","St","Sn"); # initialization of @week

then we can write

@reversed_week= reverse @week

Although we did not mention it, reverse is also defined on strings, but I was unable to find useful examples to warrant its inclusion in the sting built-in functions section.

Additional functions

The author does not mention a few very useful functions such as glob, which you had to look up elsewhere.

Unfortunately Perl set of functions for manipulating arrays and manipulating strings are unnecessary different and does not exploit similarities inherent in those who data structures.

That greatly complicates learning as the total number of functions a person can remembers is limited and it looks like Perl exceeded this number beyond human capacity with predictable results: nobody is using "full Perl", only a subset, which is manageable for a human.

Each time when I reread this chapter I discover elements that are very useful for me but completely forgotten. That's sad and suggest that the set of built-in functions in Perl is in great need of generalization and simplification.


To get the last element in a list or array, use $array[-1] instead of $array[$#array]. The former works on both lists and arrays, but the latter does not.

There are more then a dozen built-in functions for working with array, functions that are similar to functions designed for working with strings but named differently and sometimes having slightly different semantic.


Internal Links:

External Links:


Will it work or not ?

    ($first, @rest) = 1 .. Inf;
Would it be better if the type of operation was specified in the operator like in: 

We might find some short prefix character stands in for ``list'' or ``scalar''. The obvious candidates are @ and $:

    @a $+ @b
    @a @/ @b


Imitating strings using arrays

    use Tie::CharArray;
    my $foobar = 'a string';

    tie my @foo, 'Tie::CharArray', $foobar;
    $foo[0] = 'A';    # $foobar = 'A string'
    push @foo, '!';   # $foobar = 'A string!'
    print "@foo\n";   # prints: A   s t r i n g !

    tie my @bar, 'Tie::CharArray::Ord', $foobar;
    $bar[0]--;        # $foobar = '@ string!'
    pop @bar;         # $foobar = '@ string'
    print "@bar\n";   # prints: 64 32 115 116 114 105 110 103

Alternative interface functions

    use Tie::CharArray qw( chars codes );
    my $foobar = 'another string';
    my $chars = chars $foobar;  # arrayref in scalar context
    push @$chars, '?';          # $foobar = 'another string?'

    $_ += 2 for codes $foobar;  # tied array in list context
                                # $foobar = 'cpqvjgt"uvtkpiA'

    my @array = chars $foobar;  # WARNING: @array isn't tied!


In low-level programming languages such as C, and to some extent Java, strings are not primitive data types, but arrays of characters, which in turn are treated as integers. This closely matches the internal representation of strings in the memory.

Perl, on the other hand, abstracts such internal details away behind the concept of scalars, which can be treated as either strings or numbers, and appear as primitive types to the programmer. This often better matches the way people think about the data.

Sometimes, though, the low-level view is better suited for the task at hand. Perl does offer functions such as ord, chr, pack/unpack and substr that can be used to solve such tasks with reasonable efficiency. For someone used to the direct access to the internal representation offered by other languages, however, these functions may feel awkward. While this is often only a symptom of thinking in un-Perlish terms, sometimes being able to manipulate strings as character arrays really does simplify the code, making the intent more obvious by eliminating syntactic clutter.

This module provides a way to manipulate Perl strings through tied arrays. The operations are implemented in terms of the aforementioned string manipulation functions, but the programmer normally need not be aware of this. As Perl has no primitive character type, two alternative representations are provided:

Strings as arrays of single-character strings

The first way is to represent characters as strings of length 1. In most cases this is the most convenient representation, as such "characters" can be printed without explicit transformations and written as ordinary Perl string literals.

This representation is provided by the main class Tie::CharArray. As the class maps most array operations directly to calls to substr, several features of that function apply. (Below, @foo is an array tied to Tie::CharArray and $n is a positive integer.)

In general, if you only put one-character strings into the array, and don't go beyond its end, there should be no problems.

Strings as arrays of small integers

While the representation described above is usually the most convenient one, it still does not allow direct arithmetic manipulation of the character code values. For tasks where this is needed, an alternative representation is provided by the subclass Tie::CharArray::Ord. Note that it is perfectly possible to manipulate a single string through both interfaces at the same time. As the array operations are still based on substr(), the first two of the above caveats apply here as well. Unicode support depends on whether and how the underlying perl implementation supports it.

Alternative interface functions

Since using tie() can sometimes seem inconvenient, Tie::CharArray can also export two functions to perform the tying internally. The functions are reproduced below in their entirety.

sub chars ($) {
   tie my @chars, 'Tie::CharArray', $_[0];
   return wantarray ? @chars : \@chars;
sub codes ($) {
   tie my @codes, 'Tie::CharArray::Ord', $_[0];
   return wantarray ? @codes : \@codes;

When called in scalar context, they return a reference to a tied array through which the characters of the string given to them can be manipulated. In list context the functions return the tied array itself.

This is of rather limited use, since the tied array is only temporary, and assigning it to a permanent array only copies the values it contains but does not tie the permanent array. However, if the temporary array is passed to a subroutine or a foreach loop, Perl will alias the elements directly to the temporary array instead of copying them. What that means in practice is that you can write:

foreach my $ch (chars $string) {
   # reverse bits in each character
   $ch = pack "b*", unpack "B*", $ch;

Top Visited
Past week
Past month


Old News ;-)

[Nov 22, 2017] Added some information about search