Perl入门笔记——数组

Learning Perl 

第三章 列表和数组

Perl的标量表明单数(signal),表明复数(plural)的就是数组和列表。
列表指的是标量的有序集合,数组则是存储列表的变量。
列表指的是数据,数组指的是变量。
数组或列表中的每一个元素都是单独的标量变量,拥有独立的标量值。这些值是有序的,索引从0开始。
数组和列表能够包含任意多个元素。
经过数组下标,访问数组中的元素。
数组的长度是没有上限的,若是须要增补元素,那么默认取值为undef。
最后一个元素的索引为$#rocks。
从数组尾端往回计数的负数数组索引值。

列表直接量
列表直接量(list literal),有圆括号内的逗号隔开的一串数据表示,这些数据就是列表元素。
列表能够包含任意标量值:
("caoqing", "xiaohuan", "xiaobao")
..范围操做符。
(1..10)
qw
须要创建简单的单词列表,能够省去键入引号的麻烦:
qw(caoqing, xiaohuan, xiaobao)
qw表示"quoted word",Perl都当其为单引号内的字符串来处理。空白符会被迫弃,剩下的就是列表的元素。
前面的例子是一圆括号做为定界符(delimiter)。Perl容许用任何标点符号做为定界符。
qw ! caoqing xiaohuan xiaobao !
qw / caoqing xiaohuan xiaobao /
被圈引的字符串内没法使用定界符,能够经过反斜线转义字符。

列表的赋值
($caoqing, $xiaohuan, $xiaobao) = ("caoqing", "xiaohuan", "xiaobao");
当但愿引进整个数组,须要在数组名前加上@字符
@rocks = qw / caoqing xiaobao xiaohuan /;
@giant = 1..1e5;
@stuff = (@rocks, undef, @giant);
数组名会被展开成元素列表,数组只包含标量,不包含其余数组,因此数组没法成为列表里的元素。
将数组进行复制时,还是列表的赋值运算。
@copy = @quarry;

pop和push操做符
要新增元素到数组尾端时,只要将它存放在更高索引对应的新位置。
常把数组当成堆栈(stack)。
pop操做符,负责取出数组中最后一个元素并将其做为返回值返回。
@array = 1..10;
$caoqing = pop(@array);
$xiaohuan = pop(@array);
print "$caoqing, $xiaohuan";

10, 9

若是数组为空,pop返回undef。
push操做符,用于添加一个元素到数组的尾端。
push或者pop的惟一参数都是要操做的数组变量。
@array = 1..10;
push(@array, 11);
push(@array, 1..10);
@other = qw / 3, 5, 6, 2 /;
push @array, @others;

shift和unshift操做符
对应数组的左边进行相应的处理。

splice操做符
push-pop,shift-unshift操做符都是针对数组首位端操做的,splice操做符能够添加或者移除中间的元素。
最多接受四个参数,最后两个是可选参数。第一个参数是要操做的目标数组,第二个是操做的一组元素的开始位置。
@array = qw (cao qing wang huan xiao bao);
@removed = splice(@array, 3);
第三个参数指定要操做的元素长度,第四个参数是要替换的列表。
@array = qw (cao qing wang huan xiao bao);
@removed = splice(@array, 1,2,qw(pig));

字符串中的数组内插
和标量同样,数组的内容一样能够被内插到双引号串中。内插时,会自动添加分割用空格:
@rock = qw {caoqing xiaohuan xiaobao};
print "pig @rock dog\n";

pig caoqing xiaohuan xiaobao dog

数组内插时,首位都不会增长额外的空格;
数组内插时,在处理电子邮件时会有问题,要规避这种问题,须要将@转义,或者直接用单引号来定义字符串:
$email = "caoqing\@gmail.com";
$email = 'caoqing@gmail.com';
内插数组中的某个元素时,会被替换成该元素的值。
索引表达式会被当成普通字符串表达式处理。
若是要在某个标量变量后面直接写左方括号,须要先将这个方括号隔开,才不会被识别为数组引用的一部分。
@fred = qw (caoqing love xiao bao);
$fred = "xiaohuan";
print "This is $fred[3]\n";
print "This is ${fred}[3]\n";
print "This is $fred"."[3]\n";
print "This is $fred\[3\]\n";

This is bao
This is xiaohuan[3]
This is xiaohuan[3]
This is xiaohuan[3]

foreach控制结构
若是对整个列表和数组进行处理很是方便,Perl提供另外一种控制结构。
foreach(循环)中能逐项遍历列表中的值,一次迭代:
foreach $i (qw {caoqing xiaohuan xiaobao}){
  print "One name is $i.\n";
}
  
One name is caoqing.
One name is xiaohuan.
One name is xiaobao.

存储的变量在foreach循环变量循环结束后还原,没必要担忧前面是否用过同名的变量。

Perl内置变量:$_
foreach循环开头省略控制变量,Perl使用默认变量:$_。
foreach (qw {caoqing xiaohuan xiao bao}){
  print "One name is $_.\n";
}

One name is caoqing.
One name is xiaohuan.
One name is xiao.
One name is bao.

reverse操做符
reverse操做符会读取列表的值,并按照相反的顺序返回该列表。
@cao = (1..10);
@qing = reverse(@cao);
Perl会先计算等号右边要赋的值,在实际进行操做。
reverse会返回次序相反的列表,并不会修改传进来的参数。

sort操做符
sort操做符会读取列表的值,而根据内部字符编码顺序进行排序。大的字符排列在前面,数组在字母前,标点散落各处。
sort操做符的参数应该是某个输入列表,而后进行排序,继而返回排序后的列表。
@rock = qw (caoqing xiaohuan xiao bao);
@sorted = sort(@rock);
foreach (@sorted) {
  print "$_\t";
}

bao    caoqing    xiao    xiaohuan

each操做符
Perl5.12开始,能够针对数组使用each操做。以前只能用于提取哈希的键值对。
对数组调用each,会返回该元素的索引和该元素的值:
@rock = qw (caoqing xiaohuan xiao bao);
while(my ($index, $value) = each(@rock)) {
  print "$index : $value\n";
}

0 : caoqing
1 : xiaohuan
2 : xiao
3 : bao

若是不是用each实现,能够根据索引进行遍历,而后借助索引值取得元素值:
my @rock = qw (caoqing xiaohuan xiao bao);
foreach $index (0..$#rock) {
  print "$index : $rock[$index]";
}

0 : caoqing1 : xiaohuan2 : xiao3 : bao

标量上下文和列表上下文
同一个表达式出如今不一样的位置会有不一样的意义。
所谓上下文,指的是如何使用表达式。
Perl解析表达式时,要么返回标量,要么返回列表。
42 + some
sort some
some这个单词在某种状况下获得单一的标量值,而在另外状况下获得一个列表。Perl老是根据须要的上下文返回对应的值。
数组名称为例,在列表上下文,返回元素的列表;在标量上下文,返回数组中元素的个数:
@animal = qw (dog cat pig);
@sorted = sort @animal;
$number = 42 + @animal;
print "$number";

45

在标量上下文中使用产生列表的表达式
某些表达式不会在标量上下文中返回任何值。
一些常见的上下文:
$fred = something;            #标量上下文
@animal = something;        #列表上下文
($cao, $qing) = something;    #列表上下文
($bao) = something;        #列表上下文
若是给列表或者数组赋值,就是列表上下文。
标量上下文:
$fred = something;
$fred[3] = something;
123 + something;
if (something) {...};
while (something) {...};
$fred[somthing] = something;
列表上下文:
@fred = something;
($fred, $cao) = something;
($cao) = something;
push @fred, something;
foreach $fred (something) {...};
sort something;
reverse something;
print something;

在列表上下文使用产生标量的表达式
@fred = 6 * 7;
@qing = "hello" . '' . "world";

强制指定标量上下文
Perl要在列表上下文的地方强制使用标量上下文,可使用伪函数scalar。
@rocks = qw / cao qing wang huan /;
print "How many rocks do you have?\n";
print "I have ", scalar rocks, "rocks.\n";

习题
1. 写一个程序,读入一些字符串,直到文件结尾为止。而后,按照相反顺序输出这个列表。
2. 写一个程序,读入一些数字,而后根据数字输出以下名单中相应的人名。
cao qing wang huan xiao bao
3. 写一个程序,读入一些字符串,而后按照ASCII码顺序输出全部字符串。

答案:
1.
print "Please enter some lines, then press Ctrl-D:\n";
print reverse <STDIN>;
2.
@name = qw( cao qing wang huan xiao bao );
print "Enter some numbers from 1 to 6, one per line, then press Ctrl-D:\n";
chomp(@numbers = <STDIN>);
foreach (@numbers) {
    print "$name[$_ - 1]\n";
}
3.
chomp(@lines = <STDIN>);
@sorted = sort @lines;
print "sortedz\n";
相关文章
相关标签/搜索