本文主要介绍Perl的复杂数据结构,包括:
- 二维数组
- 哈希结构及复杂哈希结构
二维数组
Perl的数组由一对圆括号及用逗号分隔的元素组成(当然还有其他的声明方式)。
如:@array = ("apple","orange","pear");
二维数组声明方式有两种:
-
@array =
([1,2,3],[4,5,6],[7,8,9]);这种方式中@array表示数组,如左图。
-
$ref_array = [[1,2,3],[4,5,6],[7,8,9]];这种方式中$array表示数组的引用,如右图。
两种声明方式没有太大差别。最终都得到了一个二维数组。针对这两种声明方式,同时也有两种数组读取方式。
- $array[0][0];直接操作数组,指代第一个数组中第一个元素。
- $ref_array->[0][0];由于第二种方式是引用数组,所以使用“->”进行读取,读取的结果同上。
- 由于数组的内部仍是引用,所以两种方法的引用方式还可以写成:$array[0]->[0]和$ref_array->[0]->[0].
Perl使用push函数向数组中新增元素。
perldoc文档关于push方法的说明
-
C:\>perldoc -f push
-
push ARRAY,LIST
-
push EXPR,LIST
-
Treats ARRAY as a stack by appending the values of LIST to the
-
把数组当做一个栈,将LIST列表值追加到数组的尾部。
-
end of ARRAY. The length of ARRAY increases by the length of
-
数组的长度根据LIST列表的长度进行增加。
-
LIST. Has the same effect as
-
和下面程序的作用一样,但是效率更高。
-
for $value (LIST) {
-
$ARRAY[++$#ARRAY] = $value;
-
}
-
-
but is more efficient. Returns the number of elements in the
-
返回推送完成后数组的长度。
-
array following the completed "push".
-
-
Starting with Perl 5.14, "push" can take a scalar EXPR, which
-
从Perl5.14开始,push方法允许标量作为参数,标量必须是一个数组的引用。
-
must hold a reference to an unblessed array. The argument will
-
参数将被自动指向引用
-
be dereferenced automatically. This aspect of "push" is
-
push的这个特性是实验性的,可能在未来的版本中被改变。
-
considered highly experimental. The exact behaviour may change
-
in a future version of Perl.
-
-
To avoid confusing would-be users of your code who are running
-
earlier versions of Perl with mysterious syntax errors, put this
-
sort of thing at the top of your file to signal that your code
-
will work *only* on Perls of a recent vintage:
-
-
use 5.014; # so push/pop/etc work on scalars (experimental)
使用方法:
push 数组/数组的引用,数值/数值的列表;
针对上面两种操作方法,分别为
push $array[0],2;
push $array->[0],2;
使用delete删除二维数组元素
使用方法:
delete 指定位置元素;
delete方法并非将该元素删除,而是将其值设为undef,数组的长度不会改变,可以重新设置该元素值。
针对上面两种操作方法,分别为
delete $array[2][2];删除二维数组最后一个元素。
delete $array->[2][2];同上。
修改数组值
修改数组内容只需要取得数组元素位置,让后重新对其赋值即可。此处不做赘述。
-
#!user/bin/env perl
-
#array 2D
-
#第一种二维数组声明方法
-
my @array = ([1,2,3],[4,5,6],[7,8,9]);
-
#向二维数组第一个数组引用中新增一个值
-
$num = push $array[0],"2";
-
#$num代表新增后数组的长度
-
print "the number in array after push:$num\n";
-
print "new add element:$array[0][3]\n";
-
#delete删除元素只是将其设置为undef,$num代表删除元素的位置。
-
$num = delete $array[2][2];
-
print "the position where deleted:$num\n";
-
print "\$array[2][2]=$array[2][2]\n";
-
#重新设置值
-
$array[2][2] = 1000;
-
print "\$array[2][2]=$array[2][2]\n";
-
print "\$array[1][1]=$array[1][1]\n";
-
-
print "\n-----------------------------------------------------------------\n";
-
#第二种二维数组声明方法
-
my $ref = [[1,2,3],[4,5,6],[7,8,9]];
-
#向二维数组第一个数组引用中新增一个值
-
$num = push $ref->[0],"2";
-
#$num代表新增后数组的长度
-
print "the number in ref after push:$num\n";
-
print "new add element:$ref->[0][3]\n";
-
#delete删除元素只是将其设置为undef,$num代表删除元素的位置。
-
$num = delete $ref->[2][2];
-
print "the position where deleted:$num\n";
-
print "\$ref[2][2]=$ref->[2][2]\n";
-
#重新设置值
-
$ref->[2][2] = 1000;
-
print "\$ref[2][2]=$ref->[2][2]\n";
-
print "\$ref[1][1]=$ref->[1][1]\n";
哈希结构
哈希结构由成对的键值对构成。在内存中以散列值的方式存储,因此并不保持放入顺序。
哈希结构定义方式
-
%hash = ("Tom",50,"Tony",80,"Cindy",85);这种定义方法,要求括号内元素必须成对出现,阅读上不方便。
-
%hash = ("Tom"=>50,"Tony"=>80,"Cindy"=>85);推荐使用第二种方法,方便阅读且不易出错。
获取哈希结构的key
@key = keys %hash;
获取哈希结构的value
@value = values %hash;
通过key获取value
$value = $hash{key};
遍历哈希结构
foreach $key (keys %hash)
{
print "key:$key value:$hash{$key}\n";
}
向哈希结构中增加元素
$hash{new_key}=value;
删除哈希结构中元素
delete $hash{key};
修改哈希结构的值
$hash{key} = new_value;
-
#!user/bin/env perl
-
-
#new hash struts
-
my %English = (
-
#key #value
-
"Tom" => "50",
-
"Tony" => "80",
-
"Cindy" => "90"
-
);
-
-
#get keys
-
print "keys:\n";
-
print keys %English;#TonyTomCindy
-
-
#get values
-
print "\nvalues:\n";
-
print values %English;#805090
-
-
#get value by key
-
print "\nget value by key:Tom:$English{'Tom'}\n";
-
-
#get all key value
-
print "list all key and value\n";
-
sub func_list{
-
foreach $key (keys %English)
-
{
-
print "key:$key vlaue:$English{$key}\n"
-
}
-
}
-
func_list;
-
-
#add new element
-
print "add new element key:Taylor value:75\n";
-
$English{"Taylor"} = "75";
-
func_list;
-
-
#delete element
-
print "delete element where key = Taylor\n";
-
delete $English{"Taylor"};
-
func_list;
-
-
#update value
-
print "update value set Tom = 99\n";
-
$English{"Tom"} = "99";
-
func_list;
复杂hash结构
含有数组的哈希结构
这种方式相对简单,将哈希结构的value替换为数组即可。
整体结构如下
%hash_with_array = {
key1=>[element1,element2...],
key2=>[element1,element2...]
};
由于通过key最终智能获取到数组的引用,因此还需要使用->读取这种结构中数组的值,数组的下标根据根据需求而定。
$value = $hash_wiht_array{key}->[0];
-
#hash with arrays
-
-
my %arrayScore = (
-
"Tom" => [50],
-
"Tony"=> [85,80],
-
"Cindy"=>[91,90]
-
);
-
-
print "******Hash with array\n";
-
print "Tom $arrayScore{'Tom'}->[0]\n";
-
print "Tony $arrayScore{'Tony'}->[0]\n";
-
print "Cindy $arrayScore{'Cindy'}->[0]\n";
含有哈希结构的数组
和前面一种结构相反,这种结构是将哈希结构作为数组的元素。
数组构成如下:
@array = (
{
key1=>value1,
key2=>value2...
},
{
key1=>value1,
key2=>value2...
}
);
数组中每个位置存放着对哈希结构的引用,同样需要使用->获取想要的值
$value = $array[0]->{key1};
-
#!user/bin/env perl
-
-
#array struts with hash
-
my @scores = (
-
{
-
"Tom" => "50",
-
"Tony" => "80",
-
"Cindy" => "90"
-
},
-
{
-
"Tom" => "100",
-
"Tony" => "70",
-
}
-
);
-
-
print "******Scores:\n";
-
-
for($i=0;$i<@scores;$i++)
-
{
-
$tmp = $scores[$i];
-
print qq(Tom $tmp->{"Tom"}\n);
-
print qq(Tony $tmp->{"Tony"}\n);
-
print qq(Cindy $tmp->{"Cindy"}\n);
-
}
含有哈希结构的哈希结构
类似于第一种,只不过此时value存放的是哈希结构。
结构如下
%hash_with_hash = {
key1=>{
key1=>value1,
key2=>value2...
},
key2=>{
key1=>value1,
key2=>value2...
}
...
};
此结构的取值方式为
$value = $hash_with_hash{outer_key}->{inner_key};
-
#hash struts with hash
-
my %scores = (
-
"English" => {
-
"Tom" => "50",
-
"Tony" => "80",
-
"Cindy" => "90"
-
},
-
"Chinese" => {
-
"Tony" => "80",
-
"Cindy"=> "90"
-
}
-
);
-
-
print "******new scores\n";
-
print "English:\n";
-
print "Tom".$scores{"English"}->{"Tom"}."\n";
-
print "Tony".$scores{"English"}->{"Tony"}."\n";
-
print "Cindy".$scores{"English"}->{"Cindy"}."\n";
-
print "Chinese:\n";
-
print "Tony".$scores{"Chinese"}->{"Tony"}."\n";
-
print "Cindy".$scores{"Chinese"}->{"Cindy"}."\n";