Perl 2d Array Assignment Operator

Array is a type of Perl variable. An array variable is an ordered collection of any number (zero or more) of elements. Each element in an array has an index which is a non-negative integer. Perl arrays are (like nearly everything else in the language) dynamic:

Actually, the values of Perl array elements can only be scalars. This may sound like a limitation, if you think of scalars only as comprising numbers and strings; but a scalar can also be a reference to any perl data variable type – scalar, array, hash, etc. Therefore, by storing a reference to any data type in an array's elements, arbitrarily complexdata structures are possible. Other scalar types, such as filehandles and the special undef value, are also naturally allowed in the elements of an array.

So, given those characteristics of a Perl array, what kinds of things would you want to do with it? That is, what operations should be able to act on it? You might conceive different sets of operations, or interfaces, depending on how you expect to use an array in your program:

Here are the fundamental Perl array operations:

  • Initialize
  • Clear
  • Get count of elements
  • Get the highest index
  • Get list of element values
  • Add new elements at the end
  • Remove an element from the end
  • Adds new elements at the beginning
  • Remove an element from the beginning
  • Access one element at an arbitrary index
  • Access multiple elements at arbitrary indices
  • Insert/Delete/Replace items in the middle of an array

This tutorial focuses specifically on the array variable type. There are many things you can do in Perl with lists which will also work on arrays; for example, you can iterate over their contents using foreach. Those things are not discussed here. Also: What is the difference between a list and an array?

Initialize an array

Simple assignment does the job:

[download]

The key points are that
  1. the assignment to an array gives list context to the right hand side;
  2. the right side can be any expression which results in a list of zero or more scalar values.
The values are inserted in the array in the same order as they occur in the list, beginning with array index zero. For example, after executing

[download]

element 0 will contain 'a', element 1 will contain 'b', and so on.

Whenever an array is assigned to en masse like this, any contents it may have had before the assignment are removed!

Clear an array

Simply assign a zero-length list:

[download]

Assigning a value such as , , or will not work! Rather, it will leave the array containing one element, with that one value. That is,

[download]

are functionally identical.
Note that if your goal is to assign the one-element list to the array, omitting the parentheses is considered to be bad style, though technically they are not strictly necessary in this case.

Get count of elements

To get the "length" or "size" of an array, simply use it in a scalar context. For example, you can "assign" the array to a scalar variable:

[download]

and the scalar variable will afterwards contain the count of elements in the array. Other scalar contexts work as well:

[download]

(Yes, gives its arguments list context, but the dot (string concatenation) operator takes precedence.)

You can always force scalar context on an array by using the function named :

[download]

Note that this is a get-only property; you cannot change the length of the array by assigning a scalar to the array variable. For example, does not empty the array (as stated in the previous section, Clear an array).

Get the highest index

Often, you want to know what is the highest index in an array — that is, the index of its last element. Perl provides a special syntax for obtaining this value:

[download]

This is useful, for example, when you want to create a list of all the indices in an array:

[download]

Unlike , is a settable property. When you assign to an array's form, you cause its length (number of elements) to grow or shrink accordingly. If the length increases, the new elements will be uninitialized (that is, they'll be undef). If the length decreases, elements will be dropped from the end. (Note, however, that perl dynamically sizes arrays, so forcing the length of an array like this is not something you'd normally need to do.)

Clear an array - Round 2

Given that is assignable, you can clear an array by assigning -1 to its form. (Why -1? Well, that's what you see in if is empty.) Generally, this is not considered good style, but it's acceptable.

Another way to clear an array is . This technique should be used with caution, because it frees up some memory used internally to hold the elements. In most cases, this isn't worth the processing time. About the only situation in which you'd want to do this is if @array has a huge number of elements, and @array will be re-used after being cleared but will not hold a huge number of elements again.

Beware: As mentioned above in Clear an array, assigning does not clear an array. Unlike the case with scalars, and are not equivalent!

Get list of element values

To get the entire list of values stored in an array at any given time, simply use it in a list context:

[download]

This is useful for iterating over the list of values stored in an array, one at a time:

[download]

This works because in the control construct, the stuff inside the parentheses is expected to be a list — or, more precisely, an expression which will be evaluated in list context and is expected to result in a list of (zero or more) scalar values.

Quiz: What's the difference between these two lines of code:

[download]

Answer:

<Reveal this spoiler or all in this thread>

Remove an element from the end

The function to remove a single element from the end of an array is . Given the code:

[download]

will contain and will be left with two elements, and .

Note: By "end", we mean the end of the array with the highest index.

Add new elements at the end

Use the function to add a number of (scalar) values to the end of an array:

[download]

Remove an element from the beginning

The function removes one value from the beginning of the array. That is, it removes (and returns) the value in element zero, and shifts all the rest of the elements down one, with the effect that the number of elements is decreased by one. Given the code:

[download]

will contain and will be left with two elements, and . (You can see that is just like , but acts on the other end of the array.)

Add new elements at the beginning

In a similarly analogous way, acts on the beginning of the array as acts on the end. Given:

[download]

will contain

Access one element at an arbitrary index

The first element of an array is accessed at index 0:

[download]

Why the sigil? Remember that the elements of an array can only be scalar values. The makes sense here because we are accessing a single, scalar element out of the array. The thing inside the square brackets does not have to be an integer literal; it can be any expression which results in a number. (If the resulting number is not an integer, it will be truncated to an integer (that is, rounded toward zero).

Change the value of the last element:

[download]

Access multiple elements at arbitrary indices

By analogy, if you want to access multiple elements at once, you would use the sigil instead of the . In addition, you would provide a list of index values within the square brackets, rather than just one.

[download]

Jargon alert: this syntax for accessing multiple elements of an array at once is called an array slice.

Never forget that with an array slice the index expression is a list: it will be evaluated in list context, and can return any number (including zero) of index numbers. However many numbers are in the list of indices, that's how many elements will be included in the slice.

Beware, though: an array slice may look like an array, due to the sigil, but it is not. For example,

[download]

will not yield the number of items in the slice!

Set the second, third, and fourth elements in an array:

[download]

Sidebar: More about indices

We said earlier that array indices are non-negative integers. While this is strictly true at some level, perl conveniently lets you index elements from the end of the array using negative indices. refers to the last element, to the next-to-last element, and so on. To oversimplify a bit, acts like an alias for ... but only in the context of indexing !

So the following are equivalent:

[download]

But beware:

[download]

can not be written as:

[download]

because in this situation the -1 is an argument of the range operator, which has no idea what "highest index number" is actually wanted.

Insert/Delete/Replace items in the middle of an array

It is possible to insert items into the middle of an array and remove items from the middle of an array. The function which enables this is called . It can insert items anywhere in an array (including the ends), and it can remove (and return) any sub-sequence of items from an array. In fact, it can do both of these at once: remove some sub-sequence of items and put another list of values in their place. always returns the list of removed values, if any.

The second argument of is an array index, and as such, everything we've said about indices applies to it.

The queue-like array functions could have been implemented in terms of , as follows:

[download]

[download]

[download]

[download]

(Beware that in scalar context splice returns the last of the list of values removed; shift and pop always return the one value removed.)

Remove 3 items, beginning with the 3rd:

[download]

Insert some new values after the 3rd, without deleting any:

[download]

Replace the 4th and 5th items with three other values:

[download]

And while we're at it: Clear an array - Round 3:

[download]

Any Questions?

The Perl FAQ has a section on Arrays.

Related Resources


What about ?

Despite its name, wantarray has nothing to do with arrays. It is misnamed. It should have been named something like . It is used inside subroutines to detect whether the sub is being called in list, scalar, or void context. It returns true, false, and undef in those cases, respectively.


Other possible topics:

  • tieing arrays; the Tie::Array module
  • delete and how it doesn't work on arrays
  • exists and how it DOES work on arrays
  • Various related Perl FAQ entries
  • Array-related modules, such as those in the Array:: family
  • Traps/gotchas, such as deleting from an array while iterating over it
  • multidimensional arrays

If you have corrections or suggestions for changes to this tutorial, please /msg me if possible, rather than posting a reply. Thanks.

Can any one explain me how to handle multidimensional array?

Well, let's just quickly review what an array is. An array is a variable that holds a list of scalar values.

To access a single element of this array, we use a subscript. In perl a subscript is enclosed in square brackets . To print the first element of @array we write:

[download]

We use the scalar ($) prefix because we are referring to 1 value and we use a subscript of 0 because all arrays start with 0 as the first item (unless we change the value of mumble mumble mumble, which is deprecated).

Since an array can only hold a list of scalar values, it cannot hold an array (which is not a scalar) and multidimensional arrays are not possible in perl.

Let's take a short intermission here while we catch our breath.


This break is being sponsored by that wonderful little scalar - The Reference.

If you have done any assembler programming, you are familiar with indirect addressing. References are similar. (Okay, maybe not.) They allow us to refer to a scalar, array, hash, or any object indirectly.

What's more, they allow us to refer to these variables with a single scalar value. (Sort of like referring to a human as 'her' instead of 'that drop dead gorgeous blonde Gertrude Rose Bertrand'.)

Let's take a look at a reference to an array. To reference @array, we precede it with \:

[download]

prints:

Note, that if we increase the size of @array by 1000 elements, the reference stays the same:

[download]

prints:

We can refer to an element of an array reference with the arrow () notation:

[download]

prints:

Oh another thing, a reference refers to the original variable, if you change an element in a reference you also change it the original variable or object which is sometimes referred to as the referent.

[download]

prints:
(*disclaimer:
all variables in the preceding examples
are fictitious. Any resemblance to real
variables is purely coincidental. References
will not be directly (or indirectly) liable for
any similarities to real variables.)

This preceding break was sponsored by that wonderful little scalar - The Reference.


Well, now that your finished buying your popcorn and staring at that drop dead gorgeous blonde Gertrude Rose Bertrand. Let's look at a way to have multidimensional arrays and still use perl.

You may want to read a little about references before continuing. Perlref has some stuff in it you'll find useful. (I'm far to busy to mention them here!)

Since a reference is a scalar and an array holds a list of scalars, an array could hold a list references. Now, an array reference can refer to an element of the array it refers to with the arrow notation () just like we did with @array before the intermission.

Let's review:

[download]

prints:

[download]

prints:
And for more than one dimension:

[download]

prints:

Okay. refers to $reference1 and a reference to an array can use arrow notation to refer to it's elements.

refers to @array1's first element. Using a little algebra we can replace like terms. , so is the same as .

(Please, take a moment to write a nice email to your under appreciated algebra teacher. We'll wait for you.)

You wrote to Gertrude, didn't you? (Shame!)

Let's take a look at a reference to an array that has no name. A nameless array is (drum roll, please) anonymous. An anonymous array in perl is constructed using square brackets .

Named:

[download]

Anonymous:
So we could rewrite:

[download]

As:

[download]

prints:
"Trust in the Algebra, Luke"

Perl allows us to drop the between subscripts, so we can also write this as:

[download]

prints:

Perldsc has a section titled 'ARRAYS OF ARRAYS' that gives more examples of declaring and generating an array of array references (a.k.a. multidimensional arrays). Note that an array can contain references to arrays of differing sizes:

[download]

Data::Dumper provides a the Dumper sub which will print an array of array references. This is a great debugging tool:

[download]

Here's the output one array:

[download]

Finally, take a look at Perllol which describes Manipulating Arrays of Arrays in Perl and Perldata, especially the part about slices (and apple pie).




"The only dumb question is the one you fail to ask."

Update (2 FEB 2009): Fixed a typo and changed array name.

Update (5 JUN 2012): Added missing code tags around Data::Dumper code.

Re: Multidimensional Arrays
by chipmunk (Parson) on Jun 22, 2001 at 20:18 UTC
    The syntax is unsupported; it was never really intended to work in the first place.

    The perldelta that comes with 5.6.1 explains:

    [download]

    I think that your tutorial is somewhat misleading, because you seem to suggest that is a standard idiom.
[reply]
[d/l]
[select]

      Well, I haven't gotten aroud to installing 5.6.1 and I probably would have missed this. Would you mind rereading the tutorial. I edited it with your comment in mind and would like to know if it screwed up the logical flow.


      Thank You,
      Charles
[reply]
        great tutorial. I was really struggling trying to grasp the concept, I had read everything I could, but nothing seemed to sink in until I read this article! Charles, you have a gift. I almost did not read the article due to the name, perhaps you could mention reference. I wish some of the posts on why NOT to use symbolic references had a link to this article... Another intersting chapter might be using hashes in a reference.
[reply]
Re: Multidimensional Arrays
by Anonymous Monk on May 28, 2003 at 07:47 UTC
    Beautiful description. I too have tried over and over to learn this. I ended up creating a moc multi-dimentional array with a hash:

    # dbl Quotes required!

    I can iterate through the array answers for Q1 like this:

    As an added benefit, I can also create other "properties":

    So, that makes it sort of like a virtual object, which I need to learn someday. This was great. Thanks again. -sleve

[reply]
[d/l]
[select]
Re: Multidimensional Arrays
by vili (Monk) on Jul 22, 2003 at 23:58 UTC
    Useful, and to the point.
    Thanks fo taking the time.
    ~vili
[reply]
Re: Multidimensional Arrays
by Sameet (Beadle) on Apr 30, 2004 at 06:25 UTC
    Hi, I am a newbie, and this node was surely very useful. Thank you
    Sameet
[reply]

      You're welcome. Glad you liked it.

[reply]
Re: Multidimensional Arrays
by Anonymous Monk on Aug 25, 2004 at 02:19 UTC
    Thanks for this tutorial, a quick google search lead me to this page. Got the answer I needed faster than by searching the perl docs.

    I was trying...
    ;
    but that didn't work.
    What I needed was

    so that I can read a value directly with


    Thanks again.

[reply]
[d/l]
[select]
Re: Multidimensional Arrays
by Anonymous Monk on Mar 18, 2003 at 22:21 UTC
    I hate to pick nits...no, wait. I love to pick nits. Well, nevermind then. What I mean is, to be accurate, "Using a little algebra we can replace like terms." is incorrect. $reference1 and $array[0[]] aren't like terms at all, they're entirely different variables. They *are* equal terms. Maybe we should email *your* algebra teacher... :)

    Hey! Are you even listening? Hello? Oh, put the picture down already!
[reply]
Re: Multidimensional Arrays
by Anonymous Monk on Nov 25, 2004 at 09:29 UTC

    [download]

    what am i doing wrong ?
[reply]
[d/l]
      You could try:

      [download]

      using an array to hold the row, or:

      [download]

      using a ref to the row. You should also consider , BTW...
[reply]
[d/l]
[select]

      has a single element - a reference to a reference to an array.

      Try:

      Update: fixed typo

[reply]
[d/l]
[select]
        This works, too:

        [download]

        I think ist is a little bit clearer (from in to out): 1. fetch array element 0, 2. dereference, 3. treat it like an array, 4. fetch via .

        But this all looks really ugly. It would be better to fix the strange assignment to than to use such a complicated expression just to fetch a value...

[reply]
[d/l]
[select]
Re: Multidimensional Arrays
by Anonymous Monk on Oct 21, 2008 at 02:15 UTC
    Hi and thanks for the great tutorial...one small note use Data::Dumper; print Dumper \@array; should be... use Data::Dumper; print Dumper \@shapes; Thanks again
[reply]
Re: Multidimensional Arrays
by Anonymous Monk on Oct 14, 2004 at 06:27 UTC
    Apart from having the drop dead looks, you also write very well. Your tutorials gives a good picture of arrays in arrays and the difference between arrays using () and []. Thanks Kasp
[reply]
Re: Multidimensional Arrays
by sapnac (Beadle) on Jul 06, 2005 at 19:16 UTC
    Thanks Charles
    This really well written and clears the concept

    Keep up the good work

    Sapna
[reply]
Re: Multidimensional Arrays
by czyker (Initiate) on Sep 19, 2011 at 18:34 UTC
    Thank you SO much. Finally an explanation that makes sense. This is absolutely outstanding.
[reply]

Back to Tutorials

0 Thoughts to “Perl 2d Array Assignment Operator

Leave a comment

L'indirizzo email non verrĂ  pubblicato. I campi obbligatori sono contrassegnati *