Slicing arrays and hashes

[ Perl tips index ]
[ Subscribe to Perl tips ]

As well as dealing with a single element from an array or hash, Perl allows us to refer to multiple elements at the same time. This is called a slice.

Array slices

When we ask for a single element from an array via a look-up, we precede the name of the array with a $ sign. This tells Perl we want a scalar.

When we're slicing an array, we precede the name of the array with a @ sign. This tells Perl that we expect to receive multiple items.

        my @big_array = ( 0 .. 200 );

        my @slice = @big_array[ 20 .. 50 ];

In the above code, @slice will be populated with the 20th through to the 50th elements from @big_array (which are the numbers 20 - 50).

We can use slices to change the values in the array:

        @big_array[ 20 .. 50 ] = ( 10 .. 20 );

or to assign values to variables:

        # assigns last four values from array to variables
        my ($a, $b, $c, $d) = @big_array[ -1 .. -4 ];

we can even use slices on the results of functions which return lists:

        my ($day, $month, $year) = (localtime())[3, 4, 5];

although in this case, notice that we don't use a @ character as we are not accessing an array.

Hash slices

Hash slices are very similar to array slices. In a hash slice, we precede the name of the hash with an @ sign as we expect to be dealing with multiple items.

        # simple hash slice
        my @values = @hash{$key1, $key2, $key3, $key4};

As with array slices we can use hash slices to change the values in the hash:

        my %age_of_friend = (
                James => 30,
                Ralph => 5,
                John => 23,
                Jane => 34,
                Maria => 26,
                Bettie => 29
        );

        # James and Ralph just had their birthdays
        @age_of_friend{ qw/James Ralph/ } = (31, 6);

or assign values to variables:

        my ($maria_age, $bettie_age) = @age_of_friend{ qw/Maria Bettie/ };

A common use of hash slices is to create a look-up table for data stored in an array. As hash look-ups occur in constant time while random searches across an array occur in polynomial time, using hash slices increases the efficiency of your code.

        # The array of things we'd like to test against
        my @colours = qw/red green yellow orange white mauve blue ochre
                         pink purple gold silver grey brown steel/;

        # A list of things that might be in @colours or not
        my @find = qw/red blue green black/;

        # hashes and arrays can have the same names.
        # hash slices use curly braces {} 
        # array slices use square brackets []
        my %colours;

        # set all values in %colours from the keys in @colours to 
        # have the undefined value (but exist in the hash).
        @colours{@colours} = ();

        # We now look for @find in %colours rather than @colours.  
        foreach my $colour (@find) {
                if(exists( $colours{$colour} )) {
                        print "$colour exists\n";
                }
                else {
                        print "$colour is unknown\n";
                }
        }

The uniqueness property of hash keys can also be used to remove duplicates from a list.

[ Perl tips index ]
[ Subscribe to Perl tips ]


This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.

If you have any questions please don't hesitate to contact us:

Email: contact@perltraining.com.au
Phone: 03 9354 6001 (Australia)
International: +61 3 9354 6001

Valid XHTML 1.0 Valid CSS