Perl 数组和列表

列表

  • 使用小括号包围元素,括号中的元素使用逗号隔开;
  • 列表中的元素可以是字符串、数值、undef或它们的混合;
  • 列表中的字符串需要使用引号包围;
  • 空列表是括号中什么都没有的列表,空列表返回的是undef,但是赋值给别人时,不会当作undef,而是什么都没有,也就是该列表是空的,但是不是没有定义过(见稍后的例子);

(1,2,"perl","python")
("var1","var2","var3")
()       # 空列表

if(defined(())){        # 对空列表()进行判断
    print "defined";
}else{
    print "undefined";  # 返回此行
}
  • Perl将忽略构造列表时多余的逗号 
(1,2,3,)      # 等价于(1,2,3)
(1,2,,,4)     # 等价于(1,2,4)

  • 列表中的元素支持范围操作,使用(..)即可,如果是小数,则取整,也支持负数;

  • 范围操作不支持逆序范围,但不会报错,注意,不是undef,所以也就不是空列表;

(1..5)        # 等价于(1,2,3,4,5)
(1,2,3..5,7)  # 等价于(1,2,3,4,5,7)
(3.5..6)      # 等价于(3,4,5,6)
(3.5..6.5)    # 等价于(3,4,5,6)
(-3..2)       # 等价于(-3,-2,-1,0,1,2)
($m..$n)      # 范围由$m和$n决定
(a..d)        # ("a","b","c","d")

qw简写

使用qw简写列表,各个元素之间用空格隔开,并且对于字符串不需要加引号(加上引号的话将引号作为字符串的一部分),如下两种方式等价:

("perl","python","shell")
qw(perl python shell)

 qw里虽然不用写引号,但它相当于单引号,所以qw里面不能变量替换,不能反斜线序列(如\n):

$perl="perl";
qw($perl python shell\n)   # 不会做任何转换,包含三个元素"$perl"、"python"、"shell\n"

qw会丢弃所有空白,所以可以直接换行 :

qw(
    perl
    python
    shell
)

注意,不能在qw换行内部加上注释#   ;所以,下面#和它后面的字符串也被当作列表元素:

qw(
    perl
    python   # This is python
    shell
)

qw后面的定界符可以换成其它的,只要对应就可以:

qw/ var1 var2 var3 /
qw! var1 var2 var3 !
qw% var1 var2 var3 %
qw# var1 var2 var3 #      # 这个有点像注释

如果定界符中间要包含定界符符号,只要转义就可以了 ,但是最好区别开来:

qw/ var1 var2 \/var3 var4 /    #不推荐

 比较好的方法是更换定界符,如下:

qw% var1 var2 /var3 var4 %    #推荐

 列表的赋值

perl中可以通过列表一一对应地给(标量)变量赋值,如下:

($perl,$python)=("perl","python");
print $perl,"\n";
print $python,"\n";

赋值前,总是先计算出等号右边的值,然后再赋给左边,所以交换变量非常容易 :

($perl,$python)=($python,$perl);

如果列表赋值时,等号左右两边元素个数不等,则采取如下方案:

  • 如果右边元素更多,则忽略多出来的元素;
  • 如果左边变量元素更多,则多出来的变量赋值为undef;

($perl,$python,$shell)     =qw(perl python shell php);   # php被忽略
($perl,$python,$shell,$php)=qw(perl python shell);  # $php被赋值为undef

perl中,列表和数组紧密关联,可以认为将列表赋值给一个变量,这个变量就是数组,数组使用"@"符号开头 :

@subject=("perl","python","shell");
@range=1..5;
@subject=(@subject,"hello",@range);#数组合并

对于空列表和列表中的undef元素:

  • 空列表自身是一个未定义列表,所以它自身返回undef
  • 未定义的数组,或者未定义的列表就是空列表(),因为未定义,所以它自身返回undef
  • 将空列表或者未定义的数组作为元素添加到其它列表、数组中时,等于什么都没做,直接被忽略,因为它是没定义过的
  • undef元素是一个实实在在的元素,会占用列表、数组空间

数组

Perl 数组一个是存储标量值的列表变量,变量可以是不同类型

数组变量以 @ 开头访问数组元素使用 $ + 变量名称 + [索引值] 格式来读取(索引值从0开始),实例如下:

由于元素11没有定义,所以上面报出warning;

1)$#sub 表示最大的索引值,也就是数组的长度减1,所以上面$sub[$#sub] 为最后一个元素;

2)看上面第7行与第8行直接输出数组的区别:加引号的方式输出默认会将元素按空格分隔开,而不带引号输出元素之间没有空格

3)定义数组用 @ 符号,元素放在括号内,也可以以 qw 开始定义数组,如下:

@array = (1, 2, 'Hello');#数组元素用逗号隔开
@array = qw/这是 一个 数组/;

第二个数组使用 qw/   / 运算符,它返回字符串列表,数组元素以空格分隔;当然也可以使用多行来定义数组: 

@days = qw/google
taobao
...
runoob/;

也可以按索引来给数组赋值,如下所示:

$array[0] = 'Monday';
...
$array[6] = 'Sunday';

注意看二者输出的区别:

可以看到,qw定义方式是按原样输出,字符串也不需要加引号,数组元素之间用空格区分

数组大小

数组大小由数组中的标量上下文决定;

perl中有很多上下文环境,最常出现的是标量上下文和列表上下文,perl会根据不同的上下文环境进行转换,从而获取不一样的值;

数组长度返回的是数组物理大小,而不是元素的个数,来看实例:

从输出的结果可以看出,在第23行赋值后,数组元素只有6个,但是数组长度为11;再来看一个上下文的例子:

第32行是标量上下文,所以打印出的是整个数组,而第33行将数组与换行符连接,属于标量上下文,所以打印出数组长度;

添加和删除数组元素

Perl 提供了一些有用的函数来添加和删除数组元素;

下表列出了数组中常用的操作函数:

序号类型和描述
1push (@ARRAY, LIST)

将列表的值放到数组的末尾

2pop (@ARRAY)

弹出数组最后一个值,并返回它;当没有元素可弹出时,返回undef

3shift (@ARRAY)

弹出数组第一个值,并返回它;数组的索引值也依次减一

4unshift (@ARRAY, LIST)

将列表放在数组前面,并返回新数组的元素个数 

上面的4个函数是对数组的头部和尾部元素进行操作,如果想对数组的中间元素操作,则需要用到splice() 函数;

splice 有4个参数,后两个参数可选:

  • 第一个参数为要操作的数组;
  • 第二个参数为指定从哪个索引位置开始操作;
  • 第三个参数为指定要操作的长度;
  • 第四个参数用来指定替换原数组的数据;

可以看到,perl的数组并不是固定数组,而是动态数组,可以随时增加和删除数组元素,系统自动为变化的数组分配内存空间!

也可以利用下标来切割数组,并返回切割后的新数组:

数组索引需要指定有效的索引值,可以是正数后负数,每个索引值使用逗号隔开;

如果是连续的索引,可以使用 .. 来表示指定范围;

foreach和each遍历数组

foreach可以用来遍历列表或数组,看下面的例子:

上面的 $sub1 为控制变量,在每次迭代中都会从列表或者数组中取出一个元素赋给控制变量;

迭代过程中,赋值给控制变量的其实是数组元素的引用,也就是说在 foreach 的过程中修改控制变量的值会导致数组元素的改变,如下:

each 操作符可以获取一个键值对(key/value),可以用来操作数组也可以是哈希,each 对数组操作时返回的是数组元素的索引和元素值,如下:

将字符串转换为数组

Perl 中将字符串转换为数组使用 split() 函数,语法格式如下:

split ( PATTERN  , EXPR  , LIMIT  )
参数说明:

PATTERN:分隔符,默认为空格。
EXPR:指定的字符串。
LIMIT:如果指定该参数,则指定了字符串拆分成的数组元素个数。

 

 按照指定的分隔符拆分字符串,拆分后分隔符不在数组中;

将数组转换为字符串

Perl 中将数组转换为字符串使用 join() 函数,语法格式如下:

join (EXPR, LIST)
参数说明:

EXPR:连接符。
LIST:列表或数组。

 

数组排序

Perl 中数组排序使用 sort() 函数和reverse()函数,语法格式如下:

sort (SUBROUTINE , LIST)#按照ASCII 顺序来对数组进行排序
参数说明:

SUBROUTINE:指定规则
LIST:列表或数组

reverse(LIST)  #对当前的数组顺序进行反转

注意:1)数组排序函数sort是根据 ASCII 数字值来排序。所以我们在对数组进行排序时最好先将每个元素转换为小写后再排序;

2)sort 和 reverse 函数都会返回排序后的数组,并且保持原数组顺序不变

特殊变量: $[

特殊变量 $[ 表示数组的第一索引值,一般都为 0 ,如果我们将 $[ 设置为 1,则数组的第一个索引值即为 1,第二个为 2,以此类推。实例如下:

#!/usr/bin/perl
 
# 定义数组
@sites = qw(google taobao runoob facebook);
print "网站: @sites\n";
 
# 设置数组的第一个索引为 1
$[ = 1;
 
print "\@sites[1]: $sites[1]\n";
print "\@sites[2]: $sites[2]\n";

执行以上程序,输出结果为:

网站: google taobao runoob facebook
@sites[1]: google
@sites[2]: taobao

一般情况我们不建议使用特殊变量 $[,在新版 Perl 中,该变量已废弃;

合并多个数组

数组的元素是以逗号来分割,我们也可以使用逗号来合并数组,如下所示:

也可以在数组中嵌入多个数组,并合并到主数组中:

#!/usr/bin/perl
 
@odd = (1,3,5);
@even = (2, 4, 6);
 
@numbers = (@odd, @even);
 
print "numbers = @numbers\n";

执行以上程序,输出结果为:

numbers = 1 3 5 2 4 6

list 的值 = 4 3 2
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值