Perl入門筆記——數組

Learning Perl 

第三章 列表和數組

Perl的標量表明單數(signal),表明複數(plural)的就是數組和列表。
列表指的是標量的有序集合,數組則是存儲列表的變量。
列表指的是數據,數組指的是變量。
數組或列表中的每一個元素都是單獨的標量變量,擁有獨立的標量值。這些值是有序的,索引從0開始。
數組和列表能夠包含任意多個元素。
經過數組下標,訪問數組中的元素。
數組的長度是沒有上限的,若是須要增補元素,那麼默認取值爲undef。
最後一個元素的索引爲$#rocks。
從數組尾端往回計數的負數數組索引值。

列表直接量
列表直接量(list literal),有圓括號內的逗號隔開的一串數據表示,這些數據就是列表元素。
列表能夠包含任意標量值:
("caoqing", "xiaohuan", "xiaobao")
..範圍操做符。
(1..10)
qw
須要創建簡單的單詞列表,能夠省去鍵入引號的麻煩:
qw(caoqing, xiaohuan, xiaobao)
qw表示"quoted word",Perl都當其爲單引號內的字符串來處理。空白符會被迫棄,剩下的就是列表的元素。
前面的例子是一圓括號做爲定界符(delimiter)。Perl容許用任何標點符號做爲定界符。
qw ! caoqing xiaohuan xiaobao !
qw / caoqing xiaohuan xiaobao /
被圈引的字符串內沒法使用定界符,能夠經過反斜線轉義字符。

列表的賦值
($caoqing, $xiaohuan, $xiaobao) = ("caoqing", "xiaohuan", "xiaobao");
當但願引進整個數組,須要在數組名前加上@字符
@rocks = qw / caoqing xiaobao xiaohuan /;
@giant = 1..1e5;
@stuff = (@rocks, undef, @giant);
數組名會被展開成元素列表,數組只包含標量,不包含其餘數組,因此數組沒法成爲列表裏的元素。
將數組進行復制時,還是列表的賦值運算。
@copy = @quarry;

pop和push操做符
要新增元素到數組尾端時,只要將它存放在更高索引對應的新位置。
常把數組當成堆棧(stack)。
pop操做符,負責取出數組中最後一個元素並將其做爲返回值返回。
@array = 1..10;
$caoqing = pop(@array);
$xiaohuan = pop(@array);
print "$caoqing, $xiaohuan";

10, 9

若是數組爲空,pop返回undef。
push操做符,用於添加一個元素到數組的尾端。
push或者pop的惟一參數都是要操做的數組變量。
@array = 1..10;
push(@array, 11);
push(@array, 1..10);
@other = qw / 3, 5, 6, 2 /;
push @array, @others;

shift和unshift操做符
對應數組的左邊進行相應的處理。

splice操做符
push-pop,shift-unshift操做符都是針對數組首位端操做的,splice操做符能夠添加或者移除中間的元素。
最多接受四個參數,最後兩個是可選參數。第一個參數是要操做的目標數組,第二個是操做的一組元素的開始位置。
@array = qw (cao qing wang huan xiao bao);
@removed = splice(@array, 3);
第三個參數指定要操做的元素長度,第四個參數是要替換的列表。
@array = qw (cao qing wang huan xiao bao);
@removed = splice(@array, 1,2,qw(pig));

字符串中的數組內插
和標量同樣,數組的內容一樣能夠被內插到雙引號串中。內插時,會自動添加分割用空格:
@rock = qw {caoqing xiaohuan xiaobao};
print "pig @rock dog\n";

pig caoqing xiaohuan xiaobao dog

數組內插時,首位都不會增長額外的空格;
數組內插時,在處理電子郵件時會有問題,要規避這種問題,須要將@轉義,或者直接用單引號來定義字符串:
$email = "caoqing\@gmail.com";
$email = 'caoqing@gmail.com';
內插數組中的某個元素時,會被替換成該元素的值。
索引表達式會被當成普通字符串表達式處理。
若是要在某個標量變量後面直接寫左方括號,須要先將這個方括號隔開,纔不會被識別爲數組引用的一部分。
@fred = qw (caoqing love xiao bao);
$fred = "xiaohuan";
print "This is $fred[3]\n";
print "This is ${fred}[3]\n";
print "This is $fred"."[3]\n";
print "This is $fred\[3\]\n";

This is bao
This is xiaohuan[3]
This is xiaohuan[3]
This is xiaohuan[3]

foreach控制結構
若是對整個列表和數組進行處理很是方便,Perl提供另外一種控制結構。
foreach(循環)中能逐項遍歷列表中的值,一次迭代:
foreach $i (qw {caoqing xiaohuan xiaobao}){
  print "One name is $i.\n";
}
  
One name is caoqing.
One name is xiaohuan.
One name is xiaobao.

存儲的變量在foreach循環變量循環結束後還原,沒必要擔憂前面是否用過同名的變量。

Perl內置變量:$_
foreach循環開頭省略控制變量,Perl使用默認變量:$_。
foreach (qw {caoqing xiaohuan xiao bao}){
  print "One name is $_.\n";
}

One name is caoqing.
One name is xiaohuan.
One name is xiao.
One name is bao.

reverse操做符
reverse操做符會讀取列表的值,並按照相反的順序返回該列表。
@cao = (1..10);
@qing = reverse(@cao);
Perl會先計算等號右邊要賦的值,在實際進行操做。
reverse會返回次序相反的列表,並不會修改傳進來的參數。

sort操做符
sort操做符會讀取列表的值,而根據內部字符編碼順序進行排序。大的字符排列在前面,數組在字母前,標點散落各處。
sort操做符的參數應該是某個輸入列表,而後進行排序,繼而返回排序後的列表。
@rock = qw (caoqing xiaohuan xiao bao);
@sorted = sort(@rock);
foreach (@sorted) {
  print "$_\t";
}

bao    caoqing    xiao    xiaohuan

each操做符
Perl5.12開始,能夠針對數組使用each操做。以前只能用於提取哈希的鍵值對。
對數組調用each,會返回該元素的索引和該元素的值:
@rock = qw (caoqing xiaohuan xiao bao);
while(my ($index, $value) = each(@rock)) {
  print "$index : $value\n";
}

0 : caoqing
1 : xiaohuan
2 : xiao
3 : bao

若是不是用each實現,能夠根據索引進行遍歷,而後藉助索引值取得元素值:
my @rock = qw (caoqing xiaohuan xiao bao);
foreach $index (0..$#rock) {
  print "$index : $rock[$index]";
}

0 : caoqing1 : xiaohuan2 : xiao3 : bao

標量上下文和列表上下文
同一個表達式出如今不一樣的位置會有不一樣的意義。
所謂上下文,指的是如何使用表達式。
Perl解析表達式時,要麼返回標量,要麼返回列表。
42 + some
sort some
some這個單詞在某種狀況下獲得單一的標量值,而在另外狀況下獲得一個列表。Perl老是根據須要的上下文返回對應的值。
數組名稱爲例,在列表上下文,返回元素的列表;在標量上下文,返回數組中元素的個數:
@animal = qw (dog cat pig);
@sorted = sort @animal;
$number = 42 + @animal;
print "$number";

45

在標量上下文中使用產生列表的表達式
某些表達式不會在標量上下文中返回任何值。
一些常見的上下文:
$fred = something;            #標量上下文
@animal = something;        #列表上下文
($cao, $qing) = something;    #列表上下文
($bao) = something;        #列表上下文
若是給列表或者數組賦值,就是列表上下文。
標量上下文:
$fred = something;
$fred[3] = something;
123 + something;
if (something) {...};
while (something) {...};
$fred[somthing] = something;
列表上下文:
@fred = something;
($fred, $cao) = something;
($cao) = something;
push @fred, something;
foreach $fred (something) {...};
sort something;
reverse something;
print something;

在列表上下文使用產生標量的表達式
@fred = 6 * 7;
@qing = "hello" . '' . "world";

強制指定標量上下文
Perl要在列表上下文的地方強制使用標量上下文,可使用僞函數scalar。
@rocks = qw / cao qing wang huan /;
print "How many rocks do you have?\n";
print "I have ", scalar rocks, "rocks.\n";

習題
1. 寫一個程序,讀入一些字符串,直到文件結尾爲止。而後,按照相反順序輸出這個列表。
2. 寫一個程序,讀入一些數字,而後根據數字輸出以下名單中相應的人名。
cao qing wang huan xiao bao
3. 寫一個程序,讀入一些字符串,而後按照ASCII碼順序輸出全部字符串。

答案:
1.
print "Please enter some lines, then press Ctrl-D:\n";
print reverse <STDIN>;
2.
@name = qw( cao qing wang huan xiao bao );
print "Enter some numbers from 1 to 6, one per line, then press Ctrl-D:\n";
chomp(@numbers = <STDIN>);
foreach (@numbers) {
    print "$name[$_ - 1]\n";
}
3.
chomp(@lines = <STDIN>);
@sorted = sort @lines;
print "sortedz\n";
相關文章
相關標籤/搜索