陣列的第二單元有更多陣列的操作,在PERL裡面會常用到
陣列的合併
合併陣列用清單的方式即可
@reds =qw(red pink purple); @blues = qw(blue cyan navy); @color = (@reds, @blues); print "@color\n"; # red pink purple blue cyan navy
這裡觀察到 PERL直接把兩個陣列作黏合,並非陣列中的陣列。
抽出陣列
在 [PERL] 06-運算子 #2 的範圍運算子中有提過很簡單的方法就能抽出一段陣列
@slice= @array[4..12]; #切出第4到第12 @slice= @array[-5..-1]; #切出倒數第5到尾端 @slice= @array[0,3,4,6]; #切出第0,3,4,5項
字串和陣列
字串轉陣列
$str = "12,13,44,56,75,23";; print @num= split(/,/, $str);
在split這個函式中的分隔判斷是採用比對的方式,這樣給程式非常多的彈性,不再限於單一字元或類型。
例如假設得到一個姓名的字串,名字中有空白、或定位字元,而且前後都有多個空白字元:
$str= " John<定位字元>Mary Janny Peter ";
一體適用當成同一分隔來拆開
@name = split(/\s+/, $str); print "@name"; # John Mary Janny Peter
這在剖析檔案時很好用,上面的第2行,比對的樣式為 [,\s]+ ,在04-基本比對 有提到過
\s 在PERL代表了 空白和定位字元
+ 是出現一個以上,所以多個連續字元的話還是視為一個。
@name 拆出來的結果:
('', 'John', 'Mary', 'Janny', 'Peter)
字串前面因為有一個空白,所以會多拆一個空字元陣列,也許要解決這個方法很簡單,只要先把字串給trim就行了
$str= trim( $str); # 誤!
當然你會得到錯誤,因為PERL沒有提供這樣的函數,其實也不必要,如果你的確想用這樣的函數,可以參考 [PERL] 自寫 trim, ltrim, rtrim 函數我寫的方法。
其實在PERL可以用更簡單的方法來達成,樣式改成這樣即可:
@name = split(' ', $str);
這裡用 ' '來代替 /\s+/,這兩個是等義的,但在split 函數有對 ' ' 多特別的待遇,會略過一開始的空白或定位。
陣列轉字串
@num = (12,13,15,17,18,20,201,204,300); print $str = join(',', @num); # 12,13,15,17,18,20,201,204,300
陣列的操作
陣列有幾種操作方法
push 從後面加入
pop 從後面抽出
shift 從最前面抽出,後面項目往前遞補
unshift 從最前面加入,後面項目往後擠
splice 刪除項目,從指定位置塞入項目
直接看範例
@solar = qw(sun mercury venus earth moon); push @solar, 'mars'; # sun mercury venus earth moon mars @solar = qw(sun mercury venus earth moon); pop @solar; # sun mercury venus earth @solar = qw(sun mercury venus earth moon); shift @solar; # mercury venus earth moon @solar = qw(sun mercury venus earth moon); unshift @solar, 'oort'; # oort sun mercury venus earth moon mars
splice 函數有多種參數,假設原本的陣列是
@solar = qw(sun mercury venus earth moon);
@removed就是被刪除或是抽出的陣列,所以也可以用這個函數抽出一段陣列,差別在於這個抽出後,原本的陣列項目就不見了。
# 刪除全部項目 @removed =splice( @solar); # @solar=() # @removed = (sun mercury venus earth moon) # 從索引3處刪到尾端 @removed =splice( @solar,3); # @solar= (sun mercury venus) # @removed = (earth moon) # 從索引1處刪除2個項目 @removed =splice( @solar,1,2); # sun earth moon # @solar= (sun earth moon) # @removed = (mercury venus)
splice還能順便插入項目
# 從索引1處刪除3個項目,並把 @planets陣列塞進去 @planets = qw(jupiter saturn uranus neptune); @removed =splice( @solar,1,3,@planets); # @solar= (sun jupiter saturn uranus neptune moon) # @removed = (mercury venus earth)
刪除一個項目
刪除一個項目比較麻煩
錯誤方法,該項目為undef但依然存在
$array[3]=undef;
正確方法,用splice
splice( @array,索引值,1);
陣列排序
陣列的最後面寫排序,順向排序(a->z)用 sort,反向排序(z->a)用reverse+sort
@solar = qw(sun mercury venus earth moon); @odr = sort(@solar); @descodr = reverse(sort(@solar)); print "@solar\n"; #原來的順序和陣列不變 sun mercury venus earth moon print "@odr\n"; # 順向排序的結果 earth mercury moon sun venus print "@descodr\n"; # 順向排序的結果 venus sun moon mercury earth
自定排序
上面那種排序一定不夠用的,因為排序有很多種條件,例如我之前 [PHP] 陣列排序 sort, ksort, asort, usort... 舉過的例子,我希望能照 A K Q J 10 9..2的順序排序,我把程式改寫成PERL
@poker = (qw(A K Q J), 2..10); @s = sort { $order= "AKQJ1098765432"; index($order, $a) <=> index($order, $b); } @poker; print "@poker\n"; #原來陣列不變 A K Q J 2 3 4 5 6 7 8 9 10 print "@s\n"; # 排序後的陣列 A K Q J 10 9 8 7 6 5 4 3 2
第1行 建立樸克的陣列,我懶得一個個打,所以用上面教的陣列相黏法來產生
第3行 排序後的陣列是@s,裡面用我自訂的排序方式:
我的自訂排序法只有二行,第5行定義順序,第6行使用函數 index,作用是尋找字串$a或$b在$order中的位置,再使用一個 05-運算子 #1 比較運算子中提過的數值比較運算 '<=>'即可。
自訂排序基本上就是比較進階的部分,因此點到為止。下一篇要寫PERL裡很有特色的雜湊。
上一篇 07-陣列 #1 -- 基本
回到目錄 01-撰寫第一隻PERL程式
下一篇 09-雜湊