5.4. Array Functions
Arrays can grow and shrink. The Perl array functions allow you to insert or delete elements of the array from the front, middle, or end of the list.
5.4.1. The chop and chomp Functions (with Lists)
The chop function chops off the last character of a string and returns the chopped character, usually for removing the newline after input is assigned to a scalar variable. If a list is chopped, chop will remove the last letter of each string in the list.
The chomp function removes the last character of each element in a list if it ends with a newline and returns the number of newlines it removed.
Example 5.31.
(In the Script)
# Chopping and chomping a list
1 @line=("red", "green", "orange");
2 chop(@line); # Chops the last character off each
# string in the list
3 print "@line";
4 @line=( "red", "green", "orange");
5 chomp(@line); # Chomps the newline off each string in the list
6 print "@line";
(Output)
3 re gree orang
6 red green orange
The array @line is assigned list elements. The array is chopped. The chop function chops the last character from each element of the array. The chopped array is printed. The array @line is assigned elements. The chomp function will chop off the newline character from each word in the array. This is a safer function than chop. Since there were no newlines on the end of the words in the array, it was not chomped.
|
|
5.4.2. The exists Function
The exists function returns true if an array index (or hash key) has been defined, and false if it has not.
Example 5.32.
#!/usr/bin/perl
1 @names = qw(Tom Raul Steve Jon);
2 print "Hello $names[1]\n", if exists $names[1];
3 print "Out of range!\n", if not exists $names[5];
(Output)
2 Hello Raul
3 Out of range!
An array of names is assigned to @names. If the index 1 is defined, the exists function returns true and the string is printed. If the index 5 does not exist (and in this example it doesn't), then the string Out of range! is printed.
|
|
5.4.3. The delete Function
The delete function allows you to remove a value from an element of an array but not the element itself. The value deleted is simply undefined.
Example 5.33.
(The Script)
# Removing an array element
1 @colors=("red","green","blue","yellow");
2 print "@colors\n";
3 delete $colors[1]; # green is removed
4 print "@colors\n";
5 print $colors[1],"\n";
6 $size=@colors; # value is now undefined
7 print "The size of the array is $size.\n";
(Output)
2 red green blue yellow
4 red blue yellow
7 The size of the array is 4.
|
5.4.4. The grep Function
The grep function evaluates the expression (EXPR) for each element of the array (LIST). The return value is another array consisting of those elements for which the expression evaluated as true. As a scalar value, the return value is the number of times the expression was true (i.e., the number of times the pattern was found).
Example 5.34.
(The Script)
# Searching for patterns in a list
1 @list = (tomatoes, tomorrow, potatoes, phantom, Tommy);
2 $count = grep( /tom/i, @list);
@items= grep( /tom/i, @list);
print "Found items: @items\nNumber found: $count\n";
(Output)
4 Found items: tomatoes tomorrow phantom Tommy
Number found: 4
The array @list is assigned list elements. The grep function searches for the regular expression tom. The i turns off case sensitivity. When the return value is assigned to a scalar, the result is the number of times the regular expression was matched. grep again searches for the regular expression tom. The i turns off case sensitivity. When the return value is assigned to an array, the result is a list of the matched items.
|
|
5.4.5. The join Function
The join function joins the elements of an array into a single string and separates each element of the array with a given delimiter—the opposite of split (see "The split Function" on page 110). It can be used after the split function has broken a string into array elements. The expression DELIMITER is the value of the delimiter that will separate the array elements. The LIST consists of the array elements.
Example 5.35.
(The Script)
# Joining each elements of a list with colons
1 $name="Joe Blow";
$birth="11/12/86";
$address="10 Main St.";
2 print join(":", $name, $birth, $address ), "\n";
(Output)
2 Joe Blow:11/12/86:10 Main St.
A string is assigned to a scalar. The join function joins the three scalars, using a colon delimiter, and the new string is printed.
|
|
Example 5.36.
(The Script)
# Joining each element of a list with a newline
1 @names=('Dan','Dee','Scotty','Liz','Tom');
2 @names=join("\n", sort(@names));
3 print @names,"\n";
(Output)
3 Dan
Dee
Liz
Scotty
Tom
The array @names is assigned a list. The join function will join each word in the list with a newline (\n) after the list has been sorted alphabetically. The sorted list is printed with each element of the array on a line of its own.
|
5.4.6. The map Function
The map function maps each of the values in an array to an expression or block, returning another array with the results of the mapping. This is easier to demonstrate in an example than to describe in words.
map EXPR, LIST;
map {BLOCK} LIST;
Example 5.37.
(The Script)
# Mapping a list to an expression
1 @list=(0x53,0x77,0x65,0x64,0x65,0x6e,012);
2 @words = map chr, @list;
3 print @words;
4 @n = (2, 4, 6, 8);
5 @n = map $_ * 2 + 6, @n;
6 print "@n\n";
(Output)
3 Sweden
6 10 14 18 22
The array @list consists of six hexadecimal numbers and one octal number. The map function maps each item in @list to its corresponding chr (character) value and returns a new list. The new list is printed. Each numeric value was converted with the chr function to a character corresponding to its ASCII value. The array @n consists of a list of integers. The map function evaluates the expression for each element in the @n array and returns the new list to @n, resulting from the evaluation. The results of the mapping are printed.
|
|
Example 5.38.
Code View: (The Script)
# Map using a block
1 open(FH, "datebook.master") or die;
2 @lines=<FH>;
3 @fields = map { split(":") } @lines;
4 foreach $field (@fields){
5 print $field,"\n";
}
(Output)
5 Sir Lancelot
837-835-8257
474 Camelot Boulevard, Bath, WY 28356
5/13/69
24500
Tommy Savage
408-724-0140
1222 Oxbow Court, Sunnyvale, CA 94087
5/19/66
34200
Yukio Takeshida
387-827-1095
13 Uno Lane, Asheville, NC 23556
7/1/29
57000
Vinh Tranh
438-910-7449
8235 Maple Street, Wilmington, VT 29085
9/23/63
68900
The datebook.master file is opened for reading from the FH filehandle. Each line consists of colon-separated fields terminated by a newline. The contents of the file are read and assigned to @lines. Each line of the file is an element of the array. The map function uses the block format. The split function splits up the array at colons, resulting in a list where each field becomes an element of the array. The foreach loop iterates through the array, assigning each element, in turn, to $field. The display demonstrates the results of the mapping. Before mapping, the line was: Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
|
5.4.7. The pack and unpack Functions
The pack and unpack functions have a number of uses. These functions are used to pack a list into a binary structure and then expand the packed values back into a list. When working with files, you can use these functions to create uuencoded files, relational databases, and binary files.
The pack function converts a list into a scalar value that may be stored in machine memory. The TEMPLATE is used to specify the type of character and how many characters will be formatted. For example, the string c4, or cccc, packs a list into 4 unsigned characters, and a14 packs a list into a 14-byte ASCII string, null padded. The unpack function converts a binary formatted string into a list, and puts a string back into Perl format.
Table 5.2. The Template pack and unpack—Types and Values
Template | Description |
---|
a | An ASCII string (null padded) |
A | An ASCII string (space padded) |
b | A bit string (low-to-high order, like vec) |
B | A bit string (high-to-low order) |
c | A signed char value |
C | An unsigned char value |
d | A double-precision float in the native format |
f | A single-precision float in the native format |
h | A hexadecimal string (low nybble first, to high) |
H | A hexadecimal string (high nybble first) |
i | A signed integer |
I | An unsigned integer |
l | A signed long value |
L | An unsigned long value |
n | A short in "network" (big-endian) order |
N | A long in "network" (big-endian) order |
p | A pointer to a null-terminated string |
P | A pointer to a structure (fixed-length string) |
q | A signed 64-bit value |
Q | An unsigned 64-bit value |
s | A signed short value (16-bit) |
S | An unsigned short value (16-bit) |
u | A uuencoded string |
v | A short in "VAX" (little-endian) order |
V | A long in "VAX" (little-endian) order |
w | A BER compressed unsigned integer in base 128, high bit first |
x | A null byte |
X | Back up a byte |
@ | Null fill to absolute position |
5.4.8. The pop Function
The pop function pops off the last element of an array and returns it. The array size is subsequently decreased by 1.
Example 5.39.
(In Script)
# Removing an element from the end of a list
1 @names=("Bob", "Dan", "Tom", "Guy");
2 print "@names\n";
3 $got = pop(@names); # Pops off last element of the array
4 print "$got\n";
5 print "@names\n";
(Output)
2 Bob Dan Tom Guy
4 Guy
5 Bob Dan Tom
The @name array is assigned list elements. The pop function removes the last element of the array and returns the popped item. The $got scalar contains the popped item, Guy. The new array is printed.
|
|
5.4.9. The push Function
The push function pushes values onto the end of an array, thereby increasing the length of the array.
Example 5.40.
(In Script)
# Adding elements to the end of a list
1 @names=("Bob", "Dan", "Tom", "Guy");
2 push(@names, "Jim", "Joseph", "Archie");
3 print "@names \n";
(Output)
2 Bob Dan Tom Guy Jim Joseph Archie
The array @names is assigned list values. The push function pushes three more elements onto the end of the array. The new array has three more elements appended to it.
|
|
5.4.10. The shift Function
The shift function shifts off and returns the first element of an array, decreasing the size of the array by one element. If ARRAY is omitted, then the ARGV array is shifted, and, if in a subroutine, the @_ array is shifted.
shift(ARRAY)
shift ARRAY
shift
Example 5.41.
(In Script)
# Removing elements from front of a list
1 @names=("Bob", "Dan", "Tom", "Guy");
2 $ret = shift @names;
3 print "@names\n";
4 print "The item shifted is $ret.\n";
(Output)
3 Dan Tom Guy
4 The item shifted is Bob.
The array @names is assigned list values. The shift function removes the first element of the array and returns that element to the scalar $ret, which is Bob. The new array has been shortened by one element.
|
|
5.4.11. The splice Function
The splice function removes and replaces elements in an array. The OFFSET is the starting position where elements are to be removed. The LENGTH is the number of items from the OFFSET position to be removed. The LIST consists of new elements that are to replace the old ones.
splice(ARRAY, OFFSET, LENGTH, LIST)
splice(ARRAY, OFFSET, LENGTH)
splice(ARRAY, OFFSET)
Example 5.42.
(The Script)
# Splicing out elements of a list
1 @colors=("red", "green", "purple", "blue", "brown");
2 print "The original array is @colors\n";
3 @discarded = splice(@colors, 2, 2);
4 print "The elements removed after the splice are: @discarded.\n";
5 print "The spliced array is now @colors.\n";
(Output)
2 The original array is red green purple blue brown
4 The elements removed after the splice are: purple blue.
5 The spliced array is now red green brown.
An array of five colors is created. The original array is printed. The splice function will delete elements starting at offset 2 (offset is initially 0), remove the two elements, purple and blue, and return the removed elements to another array, named @discarded. The splice removed elements purple and blue and returned them to @discarded, starting at element $colors[2], with a length of two elements. The array @colors has been spliced. purple and blue were removed.
|
|
Example 5.43.
(The Script)
# Splicing and replacing elements of a list
1 @colors=("red", "green", "purple", "blue", "brown");
2 print "The original array is @colors\n";
3 @lostcolors=splice(@colors, 2, 3, "yellow", "orange");
4 print "The removed items are @lostcolors\n";
5 print "The spliced array is now @colors\n";
(Output)
2 The original array is red green purple blue brown
4 The removed items are purple blue brown
5 The spliced array is now red green yellow orange
An array of five colors is created. The original array is printed. The splice function will delete elements starting at offset 2 (offset is initially 0) and remove the next three elements. The removed elements (purple, blue, and brown) are stored in @lostcolors. The colors yellow and orange will replace the ones that were removed. The values that were removed are stored in @lostcolors and printed. The new array, after the splice, is printed.
|
5.4.12. The split Function
The split function splits up a string (EXPR) by some delimiter (whitespace by default) and returns an array. The first argument is the delimiter, and the second is the string to be split. The Perl split function can be used to create fields when processing files, just as you would with awk. If a string is not supplied as the expression, the $_ string is split.
The DELIMITER statement matches the delimiters that are used to separate the fields. If DELIMITER is omitted, the delimiter defaults to whitespace (spaces, tabs, or newlines). If the DELIMITER doesn't match a delimiter, split returns the original string. You can specify more than one delimiter, using the regular expression metacharacter [ ]. For example, [ +\t:] represents zero or more spaces or a tab or a colon.
LIMIT specifies the number of fields that can be split. If there are more than LIMIT fields, the remaining fields will all be part of the last one. If the LIMIT is omitted, the split function has its own LIMIT, which is one more than the number of fields in EXPR. (See the -a switch for autosplit mode, in Appendix A.)
split("DELIMITER",EXPR,LIMIT)
split(/DELIMITER/,EXPR,LIMIT)
split(/DELIMITER/,EXPR)
split("DELIMITER",EXPR)
split(/DELIMITER/)
split
Example 5.44.
(The Script)
# Splitting a scalar on whitespace and creating a list
1 $line="a b c d e";
2 @letter=split(' ',$line);
3 print "The first letter is $letter[0]\n";
4 print "The second letter is $letter[1]\n";
(Output)
3 The first letter is a
4 The second letter is b
The scalar variable $line is assigned the string a b c d e. The value in $line (scalar) is a single string of letters. The split function will split the string, using whitespace as a delimiter. The @letter array will be assigned the individual elements a, b, c, d, and e. Using single quotes as the delimiter is not the same as using the regular expression / /. The ' ' resembles awk in splitting lines on whitespace. Leading whitespace is ignored. The regular expression / / includes leading whitespace, creating as many null initial fields as there are whitespaces. The first element of the @letter array is printed. The second element of the @letter array is printed.
|
|
Example 5.45.
Code View: (The Script)
# Splitting up $_
1 while(<DATA>){
2 @line=split(":"); # or split (":", $_);
3 print "$line[0]\n";
}
_ _DATA_ _
Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
Fred Fardbarkle:674-843-1385:20 Park Lane, Duluth, MN 23850:4/12/23:78900
(Output)
Betty Boop
Igor Chevsky
Norma Corder
Jennifer Cowan
Fred Fardbarkle
The $_ variable holds each line of the file DATA filehandle; the data being processed is below the _ _DATA_ _ line. Each line is assigned to $_. $_ is also the default line for split. The split function splits the line, ($_), using the : as a delimiter and returns the line to the array, @line. The first element of the @line array, line[0], is printed.
|
Example 5.46.
Code View: (The Script)
# Splitting up $_ and creating an unnamed list
while(<DATA>){
1 ($name,$phone,$address,$bd,$sal)=split(":");
2 print "$name\t $phone\n" ;
}
_ _DATA_ _
Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
Fred Fardbarkle:674-843-1385:20 Park Lane, Duluth, MN 23850:4/12/23:78900
(Output)
2 Betty Boop 245–836–8357
Igor Chevsky 385–375–8395
Norma Corder 397–857–2735
Jennifer Cowan 548–834–2348
Fred Fardbarkle 674–843–1385
Perl loops through the DATA filehandle one line at a time. Each line of the file is stored in the $_ variable. The split function splits each line, using the colon as a delimiter. The array consists of five scalars, $name, $phone, $address, $bd, and $sal. The values of $name and $phone are printed.
|
Example 5.47.
Code View: (The Script)
# Many ways to split a scalar to create a list
1 $string= "Joe Blow:11/12/86:10 Main St.:Boston, MA:02530";
2 @line=split(":", $string); # The string delimiter is a colon
3 print @line,"\n";
4 print "The guy's name is $line[0].\n";
5 print "The birthday is $line[1].\n\n";
6 @str=split(":", $string, 2);
7 print $str[0],"\n"; # The first element of the array
8 print $str[1],"\n"; # The rest of the array because limit is 2
9 print $str[2],"\n"; # Nothing is printed
10 @str=split(":", $string); # Limit not stated will be one more
# than total number of fields
11 print $str[0],"\n";
12 print $str[1],"\n";
13 print $str[2],"\n";
14 print $str[3],"\n";
15 print $str[4],"\n";
16 print $str[5],"\n";
17 ( $name, $birth, $address )=split(":", $string);
# Limit is implicitly 4, one more than
# the number of fields specified
18 print $name , "\n";
19 print $birth,"\n";
20 print $address,"\n";
(Output)
3 Joe Blow11/12/8610 Main St.Boston, MA02530
4 The guy's name is Joe Blow.
5 The birthday is 11/12/86.
7 Joe Blow
8 11/12/86:10 Main St.:Boston, MA:02530
9
11 Joe Blow
12 11/12/86
13 10 Main St.
14 Boston, MA
15 02530
16
18 Joe Blow
19 11/12/86
20 10 Main St.
The scalar $string is split at each colon. The delimiter is a colon. The limit is 2. LIMIT, if not stated, will be one more than total number of fields. LIMIT is implicitly 4, one more than the number of fields specified.
|
5.4.13. The sort Function
The sort function sorts and returns a sorted array. If SUBROUTINE is omitted, the sort is in string comparison order; i.e., the array is sorted alphabetically. If SUBROUTINE is specified, the first argument to sort is the name of the subroutine, followed by a list of values to be sorted. If the string "cmp" operator is used, the values in the list will be sorted alphabetically (ASCII sort), and if the <=> operator (called the "space ship" operator) is used, the values will be sorted numerically. The subroutine returns an integer less than, equal to, or greater than 0. The values are passed to the subroutine by reference and are received by the special Perl variables $a and $b, not the normal @_ array.(See subroutines in Chapter 11 for further discussion.) Do not try to modify $a or $b, as they represent the values that are being sorted.
If you want Perl to sort your data according to a particular locale, your program should include the use locale pragma. For a complete discusion on the steps needed to do this, see: http://search.cpan.org/~nwclark/perl-5.8.8/pod/perllocale.pod
sort(SUBROUTINE LIST)
sort(LIST)
sort SUBROUTINE LIST
sort LIST
Example 5.48.
(The Script)
# Simple alphabetic sort
1 @list=("dog","cat", "bird","snake" );
print "Original list: @list\n";
2 @sorted = sort(@list);
3 print "Ascii sort: @sorted\n";
# Reversed alphabetic sort
4 @sorted = reverse(sort(@list));
print "Reversed Ascii sort: @sorted\n";
(Output)
Original list: dog cat bird snake
Ascii sort: bird cat dog snake
Reversed Ascii sort: snake dog cat bird
The @list array will contain a list of items to be sorted. The sort function performs a string (ASCII) sort on the items. The sorted values must be assigned to another list or the same list. The sort function doesn't change the orginial list. The sorted string is printed. This list is sorted alphabetically and then reversed.
|
|
ASCII and Numeric Sort Using Subroutine
Example 5.49.
(The Script)
1 @list=("dog","cat", "bird","snake" );
print "Original list: @list\n";
# ASCII sort using a subroutine
2 sub asc_sort{
3 $a cmp $b; # Sort ascending order
}
4 @sorted_list=sort asc_sort(@list);
print "Ascii sort: @sorted_list\n";
# Numeric sort using subroutine
5 sub numeric_sort {
$a <=> $b ;
} # $a and $b are compared numerically
6 @number_sort=sort numeric_sort 10, 0, 5, 9.5, 10, 1000;
print "Numeric sort: @number_sort.\n";
(Output)
Original list: dog cat bird snake
Ascii sort: bird cat dog snake
Numeric sort: 0 5 9.5 10 10 1000.
The @list array will contain a list of items to be sorted. The subroutine asc_sort() is sent a list of strings to be sorted. The special variables $a and $b compare the items to be sorted in ascending order. If $a and $b are reversed (e.g., $b cmp $a), then the sort is done in descending order. The "cmp" operator is used when comparing strings. The sort function sends a list to the asc_sort(), user-defined subroutine, where the sorting is done. The sorted list will be returned and stored in @sorted_list. This is a user-defined subroutine, called numeric_sort(). The special variables $a and $b compare the items to be sorted numerically, in ascending order. If $a and $b are reversed (e.g., $b <=> $a), then the sort is done in numeric descending order. The "<=>" operator is used when comparing numbers. The sort function sends a list of number to the numeric_sort() function and gets back a list of sorted numbers, stored in the @number_sort array.
|
Using an Inline Function to Sort a Numeric List
Example 5.50.
(The Script)
# Sorting numbers with an unamed subroutine
1 @sorted_numbers= sort {$a <=> $b} (3,4,1,2);
2 print "The sorted numbers are: @sorted_numbers", ".\n";
(Output)
2 The sorted numbers are: 1 2 3 4.
The sort function is given an unnamed subroutine, also called an inline function, to sort a list of numbers passed as arguments. The <=> operator is used with variables $a and $b to compare the numbers. The sorted numeric list is returned and stored in the array @sorted_numbers. The sorted list is printed.
|
5.4.14. The reverse Function
The reverse function reverses the elements in an array, so that if the values appeared in descending order, now they are in ascending order, and so on.
reverse(LIST)
reverse LIST
Example 5.51.
(In Script)
# Reversing the elements of an array
1 @names=("Bob", "Dan", "Tom", "Guy");
2 print "@names \n";
3 @reversed=reverse(@names),"\n";
4 print "@reversed\n";
(Output)
2 Bob Dan Tom Guy
4 Guy Tom Dan Bob
The array @names is assigned list values. The original array is printed. The reverse function reverses the elements in the list and returns the reversed list. It does not change the original array; i.e., the array @names is not changed. The reversed items are stored in @reversed. The reversed array is printed.
|
|
5.4.15. The unshift Function
The unshift function prepends LIST to the front of the array.
Example 5.52.
(In Script)
# Putting new elements at the front of a list
1 @names=("Jody", "Bert", "Tom") ;
2 unshift(@names, "Liz", "Daniel");
3 print "@names\n";
(Output)
3 Liz Daniel Jody Bert Tom
The array @names is assigned three values, Jody, Bert, and Tom. The unshift function will prepend Liz and Daniel to the array. The @names array is printed.
|
|