Perl数据类型:列表与数组

版权声明:转载请说明出处! 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 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>);   #一次读取所有行的内容,去除所有行的换行符;(更简洁的写法)

猜你喜欢

转载自blog.csdn.net/qq_39556143/article/details/84593703