【Perl】列表与数组


列表指的是标量的有序集合,而数组则是存储列表的变量

数组

  1. 假如你对索引值超过数组尾端的元素进行赋值,数组将会根据需要自动扩大——只要有可用的内存分配给Perl,数组的长度是没有上限的。如果在扩展过程中需要创建增补元素,那么它们的默认取值为undef:
$rocks[0] = 'bedrock';             #一个元素
$rocks[1] = 'slate';               #又一个
$rocks[2] = 'lava';                #再来一个
$rocks[3] = 'crushed rock';        #再来一个
$rocks[99] = 'schist';             #现在有95个undef元素
  1. 数组的最后一个元素的索引值是$#name,这个数字比数组元素的个数少1,因为还有一个编号为0的元素:
    • $rocks[$#rocks] = 'hard rock';
    • $rocks[-1] = 'hard rock';
      假如你在数组中有3个元素,则有效的负数索引值为-1(最后一个元素)、-2(中间的元素)、-3(第一个元素)。实践中,似乎没有人会使用-1以外的负数索引值

列表

  1. 列表直接量,可以由圆括号内用逗号隔开的一串数据表示,而这些数据就称为列表元素。例如:
    - (1,2,3)             #包含1,2,3这三个数字的列表
    - (1,2,3,)            #末尾的逗号会被忽略
    - ("fred",4.5)        #两个元素,“fred"和4.5
    - ( )                 #空列表,0个元素
    - (1..100)            #100个整数构成的列表

..范围操作符

上例最后一行用到了..范围操作符,该操作符会从左边的数字计数到右边,每次加1,以产生一连串的数字。
(1..5)        #与(1,2,3,4,5)相同
(1.7..5.7)   #同上,但这两个数字都会被去掉小数部分
(5..1)    #空列表,..只能向上计数
(0,2..6,10,12)    
($m..$n)    #范围由$m和$n当前的值来决定

qw简写

("fred","barney","betty","wilma","dino");
《 == 》qw( fred barney betty wilma dino );
两种写法等价

  1. qw表示"quoted word(加上引号的单词)"或"quated by whitespace(用空白圈引)"
  2. Perl会将其当成单引号内的字符串来处理(所以,在qw构建的列表中,不能像双引号内的字符串一样使用\n或$fred)。
  3. 除了以一对圆括号作为界定符,Perl还允许用任何标点符号作为界定符

列表的赋值

  1. 就像标量值可被赋值给变量一样,列表值也可被赋值给变量:
    ($fred,$barney,$dino) = ("flintstone","rubble","undef");
    左侧列表中的三个变量会依次被赋予右侧列表中对应的值,相当于分别做了三次独立的赋值操作。
  2. Perl中互换两个变量的值
    • ($fred,$barney) = ($barney,$fred);
    • ($betty[0],$betty[1]) = ($betty[1],$betty[0]);

@字符

  1. 构建一个字符串数组
($rocks[0],$rocks[1],$rocks[2],$rocks[3]) = qw/talc mica feldspar quartz/;
当你希望引用整个数组时,Perl提供了一个简单的记法。之哟啊在数组名之前加上@字符(后面没有检索用的方括号)就可以了。这种写法在赋值操作符的两边都可以使用:
@rocks = qw/ bedrock slate lava /;
@tiny = ( );       #空列表,由于空列表里没有任何元素,也就不会有undef被赋值到列表中
@giant = 1..1e5;  #包含100 000个元素的列表
@stuff = (@giant,undef,@giant); #包含200 001个元素的列表
@dino = "granite";
@quarry = (@rocks,"crushed rock",@tiny,$dino);
最后一行进行的赋值运算会将@quarry设成拥有5个元素的列表(bedrocl、slate、lava、crushed rock、granite)
  1. 数组名会被展开成(它所拥有的)元素列表,因为数组只能包含标量,不能包含其他数组,所以数组无法成为列表中的元素
  2. 要留意的是:将某个数组复制到另一个数组时,仍然算是列表的赋值运算,只不过这些列表是存储在数组里而已
    @copy = @quarry; #将一个数组中的列表复制到另一个数组

pop和push操作符

  1. pop操作符负责取出数组中最后一个元素并将其作为返回值返回
    • @array = 5..9;
    • $fred = pop(@array);
    • $barney = pop @array;
    • pop(@array);
      pop后面加不加括号都可以。Perl惯例:只要不会因为拿掉括号而改变原意,括号就是可以省略的
  2. push操作符
    • push(@array,0);
    • push @array,8;
    • push @array,1..10;
  3. push的第一个参数或者pop的唯一参数都必须是要操作的数组变量——对列表直接量进行压入(push)或弹出(pop)操作是没有意义的

shift和unshift

unshift和shift操作符是对数组的"开头"进行相应的处理。

splice操作符

  1. splice:添加或移除数据中间的某些元素
  2. splice最多可接受4个参数,最后两个参数是可选参数
  3. 第1个参数是要操作的目标数组,第二个参数是要操作的一组元素的开始位置。如果仅仅给出这两项参数,Perl会把从给定位置开始一直到末尾的全部元素取出来并返回:
    - @array = qw( pebbles dino fred barney betty );
    - $removed = splice(@array,2);
    # 在原来的数组中删除fred及其后面的元素
    # @removed变成qw( fred barney betty )
    # 而原先的@array则变成qw(pebbles dino)
  1. 第3个参数指定要操作的元素长度。通过这个参数,可以删掉数组中间的一个片段。
    @array = qw( pebbles dino fred barney betty );
    @removed = splice(@array,1,2);
    #删除dino和fred两个元素
    #@removed变成qw( dino fred );
    #而@array则变成qw(pebbles barney betty);
  1. 第4个参数是要替换的列表。可以补充新的元素到原来的数组中,替换的列表长度不一定要和拿走的元素片段一样长。
    @array = qw( pebbles dino fred barney betty );
    @removed = splice @array,1,2,qw(wilma); #删除dino和fred
    #@removed变成qw(dino fred);
    #@array变成qw(pebble wilma barney betty);
  1. 实际上添加元素列表不需要预先删除某些元素,把表示长度的第三个参数设为0,即可不加删除地插入到新列表。
    表示在第2个参数的位置插入新的列表元素

字符串中的数组内插

  1. 和标量一样,数组的内容同样可以被内插到双引号串中。内插时,会在数组的各个元素之间自动添加分隔用的空格。
@rocks = qw{ flintstone slate rubble };
print "quartz @rocks limestone\n";
  1. 数组被内插后,首尾都不会增添额外的空格
  2. 如果变量变量为邮箱格式,则该变量变量要将@转义,或直接用单引号定义邮箱字符串

foreach控制结构

foreach循环能逐项遍历列表中的值,依次迭代

foreach $rock (qw/ bedrock slate lava /){
  print "One rock is $rock.\n";
}
  1. 每次循环迭代时,控制变量($rock)都会从列表中取得新的值。
  2. 控制变量并不是列表元素的复制品——实际上,它就是列表元素本身。假如在循环中修改了控制变量的值,也就同时修改了这个列表元素。
  3. 当循环结束后,控制变量的值仍然是循环执行之前的值,Perl会自动存储foreach循环的控制变量并在循环结束之后还原。也就是说,加入你想将循环的控制变量取名为$rock的话,不必担心之前是否用过同名的变量。

Perl最喜欢用的默认变量:$_

当未告知Perl使用哪个变量或数值时,Perl都会自动使用$_ ,从而使程序员免于命名和键入新变量的痛苦。

foreach (1..10){
  print "I can count to $_!\n";
}

reverse操作符

  1. reverse操作符会读取列表的值(也可能来自数组),并按相反的次序返回该列表。(因此,加入你对范围操作符..只能递增计数感到失望,可以这样来弥补:
@fred = 6..10;
@barney = reverse(@fred);  #得10,9,8,7,6
@wilma = reverse 6..10; #同上
@fred = reverse @fred;将逆序后的结果放回原来的那个数组
  1. reverse会返回次序相反的列表,但它并不会修改传进来的参数。假如返回值无处可去,那这种操作也就变得毫无意义。

sort操作符

  1. sort操作符会读取列表的值(也可能来自数组),而且会根据内部的字符编码顺序对它们进行排序。参数是某个输入列表,然后对它排序,继而返回排序后的列表。
@rocks = qw/ bedrocks slate rubble granite /;
@sorted = sort(@rocks);  #得bedrock, granite rubble slate
@back = reverse sort @rocks;  #逆序后从slate到bedrock排列
@rocks = sort @rocks;
@number = sort 97..102; #得100,101,102,97,98,99
  1. 从最后一个例子可以看出,将数字当成字符串来排序,这样的结果会不太对。根据默认的排序规则,任何以1开头的字符串会被排在以9开头的字符串之前。
  2. 和reverse一样,不会修改参数,必须将排序后的结果存回数组

each操作符

每次对数组调用each,会返回数组中下一个元素所对应的两个值——该元素的索引以及该元素的值。

posted @ 2023-08-19 22:25  遗落在树梢的风筝  阅读(51)  评论(0编辑  收藏  举报