Perl資料型別:列表與陣列
阿新 • • 發佈:2018-12-15
列表與陣列
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>); #一次讀取所有行的內容,去除所有行的換行符;(更簡潔的寫法)