5. Operating on Arrays or Lists


1. To create a foreach() loop, a variable is provided to be used to hold the values
from an array, one element at a time.  Run the following is an example using the
foreach() command.
#! /usr/bin/perl
$USAGE = "Usage: traverse.pl"

@table = (100, 200, 300, 400);
foreach $item (@table) {
	print "The value is now ", 1000 + $item, "\n"
}
#END OF traverse.pl

2. The split() function turns a string into a list or array. It is demonstrated in 
the program pwsplit1.pl
#! /usr/bin/perl
$USAGE = "Usage: pwsplit1.pl";

$record = "joe:x:100:101:Joe Jones:/home/joe:/bin/ksh";
@fields = split (':', $record);
print "Login name is: -> $fields[0] <-\n";

print "Real Name is: ->$fields[4] <-\n";

#END OF pwsplit1.pl

What does this program produce as output? What is the nature of $record?

3. Are the following code fragments equivalent?

(a) foreach $item ("Alpha", "Beta", "Gamma", "Delta") {
      		print "The Greek alphabet is spelled $item, for example\n";
      }
      
 (b) @names = qw(Alpha Beta Gamma Delta);
      foreach $item (@names) {
      		print "The Greek alphabet is spelled $item, for example\n";
      }

4. The range operator .. can be used to generate a list.  Create a 
program that outputs the letters from k through w and then the squares of
1 through 25.

5. An alternative way of producing the output from the pwsplit1.pl program
is shown in pwsplit2.pl below.  Run the program to verify the output's the same.
#! /usr/bin/perl
$USAGE = "Usage: pwsplit2.pl";

$record = "joe:x:100:101:Joe Jones:/home/joe:/bin/ksh";

($name, $pw, $uid, $gid, $gcos) = split (':', $record);

print "Login name is: -> $name <-\n";
print "Real Name is: ->$gecos <-\n";

#END OF pwsplit2.pl

(a). Suppose the following code is appended to pwsplit2.pl:
# list slicing 
($name2, $gcose2) = (split (':', $record))[0,4];
print "Login name is: -> $name2 <-\n";
print "Real Name is: ->$gecos2 <-\n";

# Get the data from inside the print statement
$, = "\t";	# separate list items by tabs when printing
print "Logname\tIRLname]n";		# header lines separated by a tab character
print ((split ':', $record)[0,4]);
print "\n";

(b) What happened to the last two fields of $record in the pwsplit2+.pl progra?
(pwsplit2.pl and the appendix in 5(a))

(c). What would be assigned to the $gcos2 if the line was changed to be:
	($name2, $gcose2) = (split (':', $record))[0..4];

(d) Is it necessary to enclose the split() function's arguments in parentheses?

6. Run the program areverse.pl.
#! /usr/bin/perl
$USAGE = "Usage: areverse.pl";

@original = qw{On the other hand, it's better to have fingers than toes.
		Keep your feet on the ground and your head in the sky.);
$index = $#original;

# Output original Array		
foreach $w (@original) { print "$w "; } print "\n";

@backward = ();
foreach $element (@original) {
	$backward[$index] = $element;
	$index = $index -1;
}

# Output reversed Array
for each $w (@backward) { print "$w ";} print "\n";

#END OF areverse.pl

(a). Is the initial definition of $index changed if you replace it with 
$index=@original?

(b). The default variable $_ may be used to become the default loop 
variable and replace the use of $element as well as become the default 
variable for $w in the print command as:
	foreach (@original) {print} print "\n";
Revise the areverse.pl program in both foreach commands and rerun the program.

(c) The autodecrement operator may be used in the program to replace
the $index = $index - 1;  Revise the areverse.pl program to make this
more compact.

(d) What difference do you see with the change made in part (c) compared to the
output of the original program areverse.pl?

(e) What happens if you set the special variable $, to a space character in this
program?



IF IT DOESN'T WORK:

1. One solution to question 4 is the following:
	#! /usr/bin/perl
	$USAGE = "Usage: range.pl";
	foreach $letter (k..w) {
		print "Next letter is: +$letter+\n";
	}
	foreach $number (1..25) {
		print "Square of $number is [",$value**2,"]\n";
	}
	
2. The revised program in Question 5 could look like:
#! /usr/bin/perl
$USAGE = "Usage: areverse+.pl";

@original = qw{On the other hand, it's better to have fingers than toes.
		Keep your feet on the ground and your head in the sky.);
$index = $#original;

# Output original Array		
foreach (@original) { print } print "\n";

@backward = ();
foreach $element (@original) {
	$backward[$index--] = $element;
}
# Output reversed Array
for each (@backward) { print } print "\n";

# END OF areverse+.pl

Questions about the questions? Send mail to Robert Katz: rkatz@ned.highline.ctc.edu
Last Update January 17, 2002