版权声明:转载请说明出处! https://blog.csdn.net/qq_39556143/article/details/84593703
列表与数组
1. 列表和数组的定义
- 列表:指的是存储列表的有序集合;(真实的数据)
- 数组:存储列表的变量;(存储列表的容器)
- 对比与标量,列表对应于数据,数组对应于变量;
- 数组和列表的特性:
- 数组和列表的每个元素都是单独的标量变量,拥有独立的标量值,这些值是有序的(顺序固定);
- 数组和列表都有对应的整数作为索引,从0开始,依次递增;
- 数组和列表的每个元素都都是独立的,因此其类型可以不同(字符串,数字等)<一般相同>;
- 数组和列表可以包含任意多个元素;
- 使用@字符来声明一个数组;
2. 数组中的元素
- 数组元素调用方法:
#!/usr/bin/perl -w
$fred = 0;
$index = 2.345;
@fred = (yabba, dabba, doo);
print $fred; #打印0
print $fred[0]; #print yabba
print $fred[$number - 1] ; #print dabba (自动去除小数,无论正负)
print $fred[123]; #print undef
2.1 特殊的数组索引
假如你对索引值超过数组尾端的元素进行赋值,数组将会根据需要自动增大–只要能分配可用的内存,perl的数组可以无限大,见下例:
#special index
$rocks[0] = 'dedrock'; # 1 element
$rocks[1] = 'slate'; # 2 elements
$rocks[2] = 'lava'; # 3 elements
$rocks[3] = 'crushed'; # 4 elements
$rocks[99] = 'schist'; # 5 elements,and 95 undef elements
#last index of array
$end = $#rocks; # $end = 99, the last index of array
print $rocks[$#rocks]; # print "schist"
#minus index (基本没人使用除-1之外的负索引值)
print $rocks[-1]; # print "schist"
print $rocks[-100]; # print "dedrock"
print $rocks[-2000]; # ERROR!
2.2 列表和数组的赋值
- 列表直接量:直接写成数据形式的列表;
#normal list
(1,2,3) #包含元素1,2,3
(1,2,3,) #包含元素1,2,3,最后的逗号被忽略
("fred",4,5) #包含元素“fred”,4,5
() #不包含元素的空列表
(1..5) #列表(1,2,3,4,5)
(5..1) #空列表,只能向上计数
(0..$#rocks) #列表中元素为,rocks数组中的所有索引
- qw 简写
#qw style
("fred","barney","betty","wilma") #包含四个元素的列表
qw(fred barney betty wilma) #和上面列表相同
#除小括号外,也可以使用其他的定界符来帮助perl区分数组列表的边界
qw!fred barney betty wilma! #和上面列表相同
qw/fred barney betty wilma/ #和上面列表相同
qw{fred barney betty wilma} #和上面列表相同
qw[fred barney betty wilma] #和上面列表相同
qw<fred barney betty wilma> #和上面列表相同
#当列表中有某些字符的时候,使用其他的定界符便具有更大的优势
qw {
/usr/bin/perl
/usr/rootbeer/test.pl
}
- 列表的赋值
#列表赋值
($fred,$barny,$dino) = ("flintstone","rubble",undef);
($fred,$barney) = (1,2,3,4); # 3 和 4 被丢弃
($fred,$barney) = (1); # $dino的值为undef
($fred,$barney) = qw(1,2,3,4); # 3 和 4 被丢弃
#列表在赋值之前建立,因此可以在perl交换两个变量的值
($fred,$barney) = ($barney,$fred) ;
#当我们想引用整个数组时,perl提供更简便的用法:
@rocks = qw/bedrock slate lav/; # 3个元素
@tiny = (); # 空列表
@giant = 1..1e5; # 100000个元素
@stuff = (@rocks,@tiny,@giant); # 100003个元素,空列表不占位置,不计数列表为:/bedrock slate lav 1 2 3 ... 1e5/
3. 数组操作符
3.1 “pop” & “push” 操作符
- pop 和 push 的第一个参数必须是数组变量,对列表直接量进行push和pop是没有意义的;
- pop 取走数组和列表末尾的元素,并以此为返回值;
- push 将数据放入数组和列表的末尾;
#pop operation
@array = 1..5;
$fred = pop (@array); #$fred = 5
$fred = pop @array; #$fred = 4
pop @array; #@array = (1,2) now
#push operation
push @array,8; #@array = (1,2,8) now
push (@array,8); #@array = (1,2,8,8) now
push @array,1..5; #@array = (1,2,8,8,1,2,3,4,5) now
3.2 “shift” & “unshift” 操作符
- shift 和 unshift 的第一个参数必须是数组变量,对列表直接量进行shift和unshift是没有意义的;
- shift 取走数组和列表首部的元素,并以此为返回值;
- unshift 将数据放入数组和列表的首部;
#shift operation
@array = 1..5;
$fred = shift (@array); #$fred = 1
$fred = shift @array; #$fred = 2
shift @array; #@array = (4,5) now
@array1 = ();
$array_shift = shift @array1; #$array_shift = undef;
#inshift operation
unshift @array,8; #@array = (8,4,5) now
unshift (@array,8); #@array = (8,8,4,5) now
unshift @array,1..5; #@array = (1,2,3,4,5,8,8,4,5) now
3.3 “splice” 操作符
- shift & unshift,pop & push都是针对数组首尾元素操作的,而 “splice” 操作符用于操作数组中间的元素;
- splice共有4个参数,其用法见下例:
#splice operation with 2 parameter
#第一个参数指定要操作的对数组,第二个参数是要操作的元素的起始位置;
@array = 1..5;
@removed = splice @array,2; #在原来的数组中删除从3往后的元素:@removed is (3,4,5) now @array is (1,2) now
#splice operation with 3 parameter
#第三个参数是要操作的元素的个数(不是结束位置)
@array = 1..5;
@removed = splice @array,2,2; #在原来的数组中删除从3往后2个元素:@removed is (3,4) now @array is (1,2,5) now
@removed = splice @array,2,0; #在原来的数组中删除从5往后0个元素:@removed is () now @array is (1,2,5) now
#splice operation with 4 parameter
#第四个参数是要替换的列表,在第二个参数位置插入替换列表,原列表中元素向后顺移
@array = 1..5;
@removed = splice @array,2,2,(8,9); #在原来的数组中删除从3往后2个元素,并插入新列表:@removed is (3,4) now @array is (1,2,8,9,5) now
@removed = splice @array,2,0,(5,5); #在原来的数组中删除从8往后0个元素,并插入新列表:@removed is () now @array is (1,2,5,5,8,9,5) now
3.4 “sort” & “reverse” 操作符
- sort 和 reverse 用于对数组元素进行排序和倒序;
- sort 依次按照字符内部的编码数需对其进行排序;
- 大写字符在小写字符前;
- 数字排在字符之前;
- 标点符号散落在各处;
- reverse 将数组进行完全倒序的排列;
- sort 依次按照字符内部的编码数需对其进行排序;
#sort operation
@array = qw/abc guy alo pok/;
@sorted = sort (@array); #@sorted is qw/abc alo guy pok/ now
@sorted_num = sort 99..103; #@sorted_num is qw/100 101 102 103 99/ now
#那么如何使用perl对数字进行排序呢?
@sorted_num = sort { $a <=> $b } 99..103; #@sorted_num is qw/99 100 101 102 103/ now
@sorted_num = sort { $a cmp $b } 99..103; #@sorted_num is qw/100 101 102 103 99/ now
#reverse operation
@array = qw/abc guy alo pok/;
@sorted = sort (@array); #@sorted is qw/abc alo guy pok/ now
@reversed = reverse sort @array; #@revered is qw/pok guy alo abc/ now
3.5 字符串中的数组内插
- 和标量一样,数组也可以内插到双引号的字符串内。内插时,会在数组的各个元素之间自动添加分割用的空格。
#数组内插
@array = qw/abc guy alo pok/;
print "rocks @array end.\n"; #same as print "rocks abc guy alo pok end.\n"
# @ character print
$email = "[email protected]"; # 此时会调用@qq数组
#使用以下方法打印 @ 字符
print "fred\@qq.com";
print '[email protected]';
#内插数组的某个元素
@fred = qw/hello world/;
$fred = "fred";
$y = 2;
$x = "this is $fred[1]'s place."; # this is world's place.
$x = "this is ${fred}[1]'s place."; # this is fred[1]'s place.
4. 数组遍历方法
4.1 foreach结构
- 为了能够处理perl中整个数组或者列表的数据,perl提供foreach循环,他可以逐步遍历列表中的值;
- 每次迭代时,控制变量都会取得新值(如下例中的$rock,每次循环都取不同的值);
- 控制变量并不是列表元素的复制,他就是列表元素本身。如果我们在循环中修改元素的值,也就修改了这个元素。
- 当循环结束时,控制变量变回其初始值,如果最初未定义,变回undef;
#foreach syntax
foreach $rock (qw/bedrock slate lava/) {
print "One rock is $rock.\n"; #第一次循环,rock -> bedrock, 第三次循环,rock -> lava
# $rock .= "\n"; #如果采用此行,在每个列表元素后面加上换行符
}
4.2 ecah操作符
- each操作符时v5.12以后增加的操作符;
- 在此之前,each只能用于读取哈希的key-value对;
- 每次调用,each会返回下一个元素的两个参数:数组索引 + 元素值;
#each syntax
use v5.12;
$rocks = qw/bedrock slate lava/;
while (($index,$value) = each @rocks) {
print "$index: $value.\n";
}
#也可以用foreach来实现打印整个数组
foreach $index (0..$#rocks) {
print "$index: $rocks[$index].\n";
}
4.3 Perl最喜欢的默认变量“$_”
- 如果在foreach中未定义控制变量,那么系统默认采用$_变量
- Perl有许多默认变量,这是最常用的一个;
# $_ character
#ex_1
$_ = "Yaha dabba doo.\n";
print ; #默认打印$_
#ex_2
foreach (qw/bedrock slate lava/) {
print "One rock is $_.\n"; #第一次循环,rock -> bedrock, 第三次循环,rock -> lava
# $_ .= "\n"; #如果采用此行,在每个列表元素后面加上换行符
}
5. 标量上下文和列表上下文
5.1 上下文的定义
- 上下文:指的是如何使用表达式;
- 使用数字操作符时的结果就是数字;
- 使用字符串操作符的结果就是字符串;
- perl在解析表达式时,要么希望得到标量,要么希望得到列表;
#数组名称在上下文中的不同返回结果
@people = qw/fred bob betty/;
@sorted = sort @people; #@sorted is qw/betty bob fred/ now
$number = @people; #$number is 3, return the array size
5.2 标量上下文中使用产生列表的表达式
#list in scalar
@people = qw/fred bob betty/;
@sorted = reverse @people; #@sorted is qw/betty bob fred/ now #列表上下文
$number = reverse @people; #$number is "yttebbobderf" #标量上下文
$number = something; #标量上下文
@number = something; #列表上下文
($fred,$betty) = something; #列表上下文
($fred) = something; #列表上下文
print something; #列表上下文
#强行引入标量上下文scalar(没有强制引入列表的上下文,因为根本不需要)
print "there are", scalar @people, "person in array \@people.\n";
5.3 列表上下文中使用产生标量的表达式
#scalar in list
@people = 2 * 8; #得到单个元素的列表(42)
@wilma = undef; #不会得到空数组,而会得到一个元素的数组,内含一个空元素
5.4 列表上下文中的<STDIN>
- 标量上下文中,<STDIN>返回的是输入数据的下一行内容;
- 列表上下文中,<STDIN>返回的是所有剩下行的内容;
- 列表上下文中,如何规定文件或者输入数据来源结束呢?
- Unix:Ctrl+D
- Window: Ctrl+Z
#<STDIN> in list
@lines = <STDIN>; #一次读取所有行的内容;
chomp(@lines); #去除读入的所有行的换行符;
chomp(@lines = <STDIN>); #一次读取所有行的内容,去除所有行的换行符;(更简洁的写法)