2-4 ???

Perl 常用到的另一種資料型態是鎮列(Arrays),陣列是由一連串的純量(即數值或字串)所組成。陣列變數都是以「@」開頭,再加上一些英文字母或數字。下例設定一個簡單的字串陣列: @depts = ("EE", "CS", "PME", "Econ"); 一個等效的寫法是: @depts = qw(EE CS PME Econ); 其中 qw 代表 qualified word。下例則設定一個簡單的數值陣列: @numbers = (2, 3, 4, 5); 與上例等效的寫法是: @numbers = (2..5); 我們也可以把兩個陣列合成一個: @combined = (@depts, @numbers); # @combined = ("EE", "CS", "PME", "Econ", 2, 3, 4, 5); 若要取得陣列內的元素,可以直接使用索引(Indexing),索引值是從 0 開始,最大值則是陣列的元素個數減一。例如: $dept1 = $depts[0]; # $dept1 = "EE" $dept2 = $depts[1]; # $dept2 = "CS" $dept3 = $depts[2]; # $dept3 = "PME" $dept4 = $depts[3]; # $dept4 = "Econ" 特別要注意的是,在用到個別陣列元素時,要將「@」改為「$」,這是因為 @depts 是一個陣列,但其元素則是純量,所以要用 $depts[0]、$depts[1]、$depts[2] 等來代表。另外,索引值的最大值可用 $#depts 來代表,因此以上例而言,$depts[3] 和 $depts[$#depts] 是完全等效的。

若將陣列變數直接設定給一純量變數,純量變數的值會等於陣列變數的元素個數,例如:

$a = @depts; # $a = 4 若將陣列變數設定給另一個陣列變數,那麼就會有各種變化,例如: ($a) = @depts; # $a = "EE" ($a, $b) = @depts; # $a = "EE", $b= "CS" ($a, @b) = @depts; # $a = "EE", @b = ("CS", "PME", "Econ") (@c, $d) = @depts; # @c = ("EE", "CS", "PME", "Econ"); $d = undef 一般而言,Perl 會將等號左邊的第一個變數盡量填滿,再依序填入其他變數,因此在上例最後一列中,@c 被設定為所有的元素,而 $d 則完全未被設定(因此其值為「未定義」,undef)。其他設定陣列變數或更改其元素的範例可列舉如下: @new = @depts[0,1,2]; # @new = ("EE", "CS", "PME") @depts[1,2] = @depts[2,1]; # 交換 "CS”和 "PME",@depts = ("EE", "PME", "CS", "Econ") @depts[1,2,3] = @depts[2,2,2]; # @depts = ("EE", "CS", "CS", "CS") 和陣列相關的函數,可以列表如下:

函數說明
pop從陣列右端刪除元素
push從陣列右端加入元素
shift從陣列左端刪除元素
unshift從陣列左端加入元素
splice對某些陣列元素進行置換的動作
grep保留某些陣列元素
join將陣列合併成字串
map對陣列元素進行相同運算
qw/STRING/較簡易的字串設定法
reverse左右翻轉陣列元素
scalar將陣列轉成純量(即其元素個數)
sort對陣列元素進行排序
split將字串拆解成陣列
unpackpack 的反函數,可將字串依各種標準轉換成陣列,

在下列的範例中,可顯示如何增加或刪除陣列中的元素:

@a = ('A', 'B'); $a[3] = 'C'; # @a = ("A", "B", undef, "C") push(@a, "D"); # 等效於 @a = (@a, "D") $b = pop(@a); # 刪除 @a 的最右端元素 unshift(@a, "E"); # 等效於 @a = ("E", @a); $b = shift(@a); # 刪除 @a 的最左端元素 @b = reverse(@a); # @b = ("C", undef, "B", "A") 其中 push 和 pop 可從陣列右端加入或刪除元素,unshift 和 shift 可從陣列左端加入或刪除元素。下列範例說明如何對陣列進行翻轉及排序: @a = ("Sunshine", "Cloudy", "Rain"); @b = reverse(@a); # @b = ("Rain", "Cloudy", "Sunshine") @c = sort(@b); # @c = ("Cloudy", "Rain", "Sunshine") 其中 reverse 可使陣列元素左右翻轉,sort 則可對元素進行排序。

我們可用 join 來合成陣列為一字串,例如:

@a = ("A", "B", "C"); $a = join(" ", @a); # $a = "A B C" 亦可用 split 來拆解字串成為陣列,例如: $path = 'c:\win\system;c:\dos;c\perl\bin'; @path = split(/;/, $path); # @path = ("c:\win\system", "c:\dos", "c\perl\bin"); 若要對陣列變數中的每一個元素進行相同運算,可用 map 函數,在以下範例中,我們利用 map 函數來算出每個元素的長度: @a = ("shine", "rain", "cloudy"); @b = map {length($_)} @a; # $b = (5, 4, 6) 在上例中,map 事實上是呼叫了 length 函數來計算每個元素的長度,而 $_ 是一個虛擬變數,分別代表每一個陣列元素。($_ 是一個常用到的變數,我們在後面會有更詳細的介紹。)利用 map 的功能,我們可以很快地抓出索引值分別是奇數與偶數的元素,如下: @z = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); @z1 = @z[map {$_*2} 0..(@z/2)]; # @z1 = ("Mon", "Wed", "Fri", "Sun") @z2 = @z[map {$_*2+1} 0..(@z/2)]; # @z2 = ("Tue", "Thu", "Sat")

若要過濾掉陣列變數中的某一些元素,可用 grep 函數,在以下範例中,我們利用 grep 函數來保留長度大於 5 的元素:

@a = ("shine", "rain", "cloudy"); @b = grep {length($_)>5} @a; # $b = (“cloudy”) 若要將陣列元素逐一印出,下列三種方法都可以達到同樣的效果: print join("\n", @array); foreach $element (@array) { print "$element\n"; } foreach $i (0..@array-1) { print "$array[$i]\n"; } 其中有關 foreach 的用法,我們會在「控制結構」小節再詳述。

若要將鍵盤輸入直接設定成一個陣列變數,可嘗試下列範例:

@myarray = <STDIN>; chomp(@myarray); chomp(@myarray = <STDIN>); 此時 @myarray 的每一個元素即為由鍵盤輸入的每一列,列與列之間由 Enter 或 Return 鍵來區分。若使用者要結束輸入,需於鍵盤輸入 ctrl-z 後,再按 Enter 或 Return 鍵即可。

若要將某個檔案內容讀入一個陣列變數,可嘗試下列範例:

open(FILE, "test.txt") || die("Cannot open file"); @lines = <FILE>; 請注意在上例中,@lines 的每一個元素仍然包含換行符號,若要去除此符號,可用 chomp 函數。
Perl