Массивы
Что же такое массив ?
Массив-структура данных,которая позволяет хранить большое количество информации
с помощью одной переменной.
Эта структура удобна для хранения связанной информации.
В перле массив-это такая же переменная,как и другие,
за исключением того,что ее предваряет символ @ :
#!/usr/bin/perl
# define array
@friends = ("Rachel", "Monica", "Phoebe", "Chandler", "Joey", "Ross");
Массив @friends включает 6 элементов:
Доступ к элементам массива осуществляется с помощью индекса,
первый индекс - ноль ("zero-based indexing").
Пример:
#!/usr/bin/perl
# define array
@friends = ("Rachel", "Monica", "Phoebe", "Chandler", "Joey", "Ross");
# prints "Phoebe"
print $friends[2];
Можно массив определять не в один прием,а последовательно :
#!/usr/bin/perl
# define array
@friends = ("Rachel", "Monica", "Phoebe", "Chandler", "Joey", "Ross");
Это эквивалентно следующему:
#!/usr/bin/perl
# define array
$friends[0] = "Rachel";
$friends[1] = "Monica";
$friends[2] = "Phoebe";
$friends[3] = "Chandler";
$friends[4] = "Joey";
$friends[5] = "Ross";
Notice that you don't have to do anything special to bring an array
variable into existence, like declare it with a keyword or instantiate
an object to hold its values - Perl identifies the notation being used
and
creates the data structure appropriately.
Perl also allows you to replace indices with user-defined "keys", in
order to create a slightly different type of array, called a "hash" or
"associative array". Each key is unique, and corresponds to a single
value within
the array.
#!/usr/bin/perl
# define hash
%dinner = ("starter" => "fried squid rings", "main" => "roast chicken", "dessert" => "chocolate cake");
In this case, %dinner is an associative array variable containing
key-value pairs. The % symbol before the variable name indicates that
it is an associative array, while the => symbol is used to indicate
the
association between a key and its value.
Now, in order to access the value "fried squid rings", I would use the
key "starter" and the notation $dinner{"starter"}, while the value
"chocolate cake" would be accessible via $dinner{"dessert"}. Here's an
example:
#!/usr/bin/perl
# define hash
%dinner = ("starter" => "fried squid rings", "main" => "roast chicken", "dessert" => "chocolate cake");
# prints "fried squid rings"
print $dinner{"starter"};
Note the use of curly braces here around the key name, and contrast it
with the use of square braces for the index notation used in regular
arrays.
As with arrays, you can also use this notation to define an associative array incrementally - this line of code
#!/usr/bin/perl
# define hash
%dinner = ("starter" => "fried squid rings", "main" => "roast chicken", "dessert" => "chocolate cake");
is equivalent to these:
#!/usr/bin/perl
# define hash
$dinner{"starter"} = "fried squid rings";
$dinner{"main"} = "roast chicken";
$dinner{"dessert"} = "chocolate cake";
Note that when using an associative array, Perl usually re-sorts the
key-value pairs such that they are optimized for retrieval. Therefore,
it's not a good idea to rely on your original element positions when
accessing values in a hash; instead hash values should always be
accessed by their respective keys.
To modify a particular element of an array, use the index/key notation to accomplish your task, like this:
#!/usr/bin/perl
# define array
@friends = ("Rachel", "Monica", "Phoebe", "Chandler", "Joey", "Ross");
# now change one of its elements
$friends[3] = "Janice";
# array now looks like this
@friends = ("Rachel", "Monica", "Phoebe", "Janice", "Joey", "Ross");
This works with associative arrays too:
#!/usr/bin/perl
# define hash
%dinner = ("starter" => "fried squid rings", "main" => "roast chicken", "dessert" => "chocolate cake");
# change element
$dinner{"dessert"} = "tiramisu";
# hash now looks like this
%dinner = ("starter" => "fried squid rings", "main" => "roast chicken", "dessert" => "tiramisu");
You can print the contents of an array simply by using the array in a print() function call, as below:
#!/usr/bin/perl
# define array
@friends = ("Rachel", "Monica", "Phoebe", "Chandler", "Joey", "Ross");
# print contents
print "@friends ";
The fact that array values can be accessed and manipulated using a
numeric index makes them particularly well-suited for use in a loop.
Consider the following example, which asks the user for a set of values
(the user can define the size of the set), stores these values in an
array, and then prints them back out.
#!/usr/bin/perl
# get array size
print ("How many items? ");
$size = <STDIN>;
chomp ($size);
# get array values
for ($x=0; $x<$size; $x++)
{
print ("Enter item ", ($x+1), ": ");
$val = <STDIN>;
chomp ($val);
$data[$x] = $val;
}
# iterate over array
# print array values
print ("Here is what you entered: \n");
for ($x=0; $x<$size; $x++)
{
print ("Element $x: $data[$x]\n");
}
Here's what the output looks like:
How many items? 3
Enter item 1: red
Enter item 2: orange
Enter item 3: green
Here is what you entered:
Element 0: red
Element 1: orange
Element 2: green
The first thing I've done here is ask the user for the number of items
to be entered - this will tell me the size of the array. Once that
information has been obtained, it's pretty easy to set up a "for" loop
to obtain that number of values through user input at the command
prompt.. Every time the user enters one of these values, a counter
variable is incremented, this counter variable corresponds to the index
in the @data array that is being constructed as the loop executes. Once
all the values have been entered, another "for" loop is used to iterate
over the newly-minted @data array, and print the values stored in it.
The second loop runs as many times as there are elements in the array.
In this specific example, I know the size of the array because I had
the user enter it at the beginning of the script, but you can also
obtain the
array size programmatically...as you'll see on the next page.
Want to obtain the size of an array? Sure - just assign the array to a scalar variable and print the value of the scalar:
#!/usr/bin/perl
# define array
@friends = ("Rachel", "Monica", "Phoebe", "Chandler", "Joey", "Ross");
# obtain size of array
$count = @friends;
# print size and contents
print ("I have $count friends: @friends ");
If you're using a hash, the keys() and values() functions come in handy
to get a list of all the keys and values within the array.
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
# returns an array of keys
@keys = keys(%matrix);
# returns an array of values
@values = values(%matrix);
Most of the time, size and key information is used in the context of a
loop that iterates over the array. Here's an example of how this might
work in a numerically-indexed array,
#!/usr/bin/perl
# define array
@ducks = ("Huey", "Dewey", "Louie");
# get array size
$size = @ducks;
print "And heeeeeeeeeeeeeere are the ducks: ";
# iterate over array
for ($i=0; $i<$size; $i++)
{
print "$ducks[$i] ";
}
and here's an example of iterating over an associative array using the keys() function:
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
print "Say hello to the characters in The Matrix: \n";
# get the keys of the array with keys()
# then use the keys to get the corresponding value
# in a loop
foreach $k (keys(%matrix))
{
print $k, ": ", $matrix{$k}, "\n";
}
You can assign the elements of an array to scalar variables, as in the following example:
#!/usr/bin/perl
# define array
@human = ("John", "Doe");
# assign array contents to variables
($fname, $lname) = @human;
# print variables
print ("My name is $fname $lname");
This won't work with an associative array, though - for that, you need
the each() function. Every time each() runs on a hash, it creates an
array containing two elements: the hash key and the corresponding hash
value.
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
# get first pair
($character, $name) = each (%matrix);
print "$character = $name\n";
# get second pair
($character, $name) = each (%matrix);
print "$character = $name\n";
# and so on...
The each() function comes in particularly handy when you need to
iterate through an associative array, as it is well-suited for use in a
"while" loop:
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
# iterate through hash with each
# returns villain = smith hero = neo babe = trinity teacher = morpheus
while (($character, $name) = each (%matrix))
{
print "$character = $name\n";
}
You can assign the array itself to another variable, thereby creating a copy of it, as below:
#!/usr/bin/perl
# define array
@john = ("John", "Doe");
# copy array
@clone = @john;
# print copy
print ("I am a clone named @clone");
You can add an element to the end of an existing array with the push() function,
#!/usr/bin/perl
# define array
@meals = ("lunch", "tea");
# add a new element to the end of the array
push (@meals, "dinner");
# array now looks like this
@meals = ("lunch", "tea", "dinner");
and remove an element from the end with the pop() function.
#!/usr/bin/perl
# define array
@meals = ("lunch", "tea");
# remove an element from the end of the array
pop (@meals);
# array now looks like this
@meals = ("lunch");
If you need to remove an element off the top of the array instead of the bottom, you need to use the shift() function,
#!/usr/bin/perl
# define array
@meals = ("lunch", "tea");
# remove an element from the beginning of the array
shift (@meals);
# array now looks like this
@meals = ("tea");
while the unshift() function takes care of adding elements to the beginning of the array.
#!/usr/bin/perl
# define array
@meals = ("lunch", "tea");
# add an element to the beginning of the array
unshift (@meals, "breakfast");
# array now looks like this
@meals = ("breakfast", "lunch", "tea");
When dealing with associative arrays, however, it's not a good idea to
use these functions, since key-value pairs in a Perl associative array
are not always stored in the order in which they were defined.
Therefore, to
remove an element from an associative array, you should instead use the delete() function, as in the example below:
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
# delete key
delete ($matrix{"villain"});
# hash now looks like this
%matrix = ("hero" => "neo", "teacher" => "morpheus", "babe" => "trinity");
You can delete all the values in a hash simply by combining the delete() function with a "foreach" loop, as below:
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
foreach $k (keys(%matrix))
{
delete ($matrix{$k});
}
The grep() function can tell you whether or not a particular value
exists in an array. It accepts two arguments, a pattern to match and
the array in which to search, and it scans every element of the named
array for elements matching the pattern. Results, if any, are returned
as another array. The following example illustrates how this works:
#!/usr/bin/perl
# define array
@tools = ("hammer", "chisel", "screwdriver", "boltcutter", "tape", "punch", "pliers");
# search for pattern "er" in array elements
@match = grep (/er/i, @tools);
# print matching elements
# returns "hammer screwdriver boltcutter pliers"
print "@match ";
The exists() function is useful to check if a particular key exists in a hash.
#!/usr/bin/perl
# define hash
%matrix = ("hero" => "neo", "villain" => "smith", "teacher" => "morpheus", "babe" => "trinity");
# check for key existence
if (exists($matrix{"hero"}))
{
print "Neo is alive!";
}
Perl allows you to extract a subsection of an array - a so-called
"array slice" - simply by specifying the index values needed in the
slice. Consider the following example, which demonstrates:
Here's an example:
#!/usr/bin/perl
# define array
@rainbow = ("red", "green", "blue", "yellow", "orange", "violet", "indigo");
# extract slice "blue", "yellow"
@slice = @rainbow[2,3];
Or how about this one?
#!/usr/bin/perl
# define array
@rainbow = ("red", "green", "blue", "yellow", "orange", "violet", "indigo");
# extract slice "blue", "violet", "red", "indigo"
@slice = @rainbow[2,5,0,6];
You can also use a negative index for the "start" position, to force Perl to begin counting from the right instead of the left.
#!/usr/bin/perl
# define array
@rainbow = ("red", "green", "blue", "yellow", "orange", "violet", "indigo");
# extract slice "indigo", "red"
@slice = @rainbow[-1,-7];
Perl also comes with a range operator (..) which provides an alternative way of extracting array slices. Here's an example:
#!/usr/bin/perl
# define array
@rainbow = ("red", "green", "blue", "yellow", "orange", "violet", "indigo");
# extract elements 2 to 5
# slice contains "blue", "yellow", "orange", "violet"
@slice = @rainbow[2..5];
You can also use the range operator to create arrays consisting of all
the values in a range. For example, if you wanted an array consisting
of the numbers between 1 and 20 (both inclusive), you could use the
following code to generate it automatically:
#!/usr/bin/perl
# define array
@n = (1..20);
The splice() function allows you to delete a specified segment of an
array and splice in one or more values to replace it. Here's what it
looks like:
splice(array, start, length, replacement-values)
where "array" is an array variable, "start" is the index to begin
slicing at, "length" is the number of elements to remove from "start",
and "replacement-values" are the values to splice in.
Here's an example:
#!/usr/bin/perl
# define array
@rainbow = ("red", "green", "blue");
# remove elements 1 and 2
# replace with new values
splice (@rainbow, 1, 2, "yellow", "orange");
# array now looks like this
@rainbow = ("red", "yellow", "orange");
You can alter the order of elements within an array with Perl's various
array-sorting functions. The simplest of these is the reverse()
function, which merely reverses the order in which elements are stored
within an
array:
#!/usr/bin/perl
# define array
@stooges = ("larry", "curly", "moe");
# reverse it
@segoots = reverse(@stooges);
# reversed array now looks like this
@segoots = ("moe", "curly", "larry");
The sort() function can be used to re-sort the elements in an array alphabetically:
#!/usr/bin/perl
# define array
@stooges = ("larry", "curly", "moe");
# sort it
@sorted = sort(@stooges);
# sorted array now looks like this
@sorted = ("curly", "larry", "moe");
The split() function splits a string into smaller components on the
basis of a user-specified pattern, and then returns these elements as
an array.
#!/usr/bin/perl
$str = "I'm not as think as you stoned I am";
# split into individual words on whitespace delimiter
# and store in array @words
@words = split (/ /, $str);
This function is particularly handy if you need to take a string
containing a list of items (for example, a comma-delimited list) and
separate each element of the list for further processing.
Here's an example:
#!/usr/bin/perl
$str = "Rachel,Monica,Phoebe,Joey,Chandler,Ross";
# split into individual words and store in array
@arr = split (/,/, $str);
# print each element of array
foreach $item (@arr)
{
print("$item\n");
}
Obviously, you can also do the reverse - the join() function creates a
single string from all the elements of an array, gluing them together
with a user-defined separator. Reversing the example above, we have:
#!/usr/bin/perl
@arr = ("Rachel", "Monica", "Phoebe", "Joey", "Chandler", "Ross");
# create string from array
$str = join (" and ", @arr);
# returns "Rachel and Monica and Phoebe and Joey and Chandler and Ross are friends"
print "$str are friends";
|
|