[精讚] [會員登入]
1426

[PERL] 08-陣列 #2 --操作

更多perl陣列的操作,如拆開、黏合、取出、加入等等

此文完整連結 http://n.sfs.tw/11675

複製連結 [PERL] 08-陣列 #2 --操作@新精讚
(文章歡迎轉載,務必尊重版權註明連結來源)
2019-02-04 00:11:26 最後編修
2017-08-22 01:26:20 By 張○○
 

陣列的第二單元有更多陣列的操作,在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中的陣列都是一維陣列,除非使用參照的方法,否則無論怎麼結合都是一元陣列。

抽出陣列

[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,裡面用我自訂的排序方式:

@排序完陣列= sort { 自訂排序法 } @原陣列

我的自訂排序法只有二行,第5行定義順序,第6行使用函數 index,作用是尋找字串$a或$b在$order中的位置,再使用一個 05-運算子 #1 比較運算子中提過的數值比較運算 '<=>'即可。

自訂排序基本上就是比較進階的部分,因此點到為止。下一篇要寫PERL裡很有特色的雜湊。

上一篇 07-陣列 #1 -- 基本
回到目錄 01-撰寫第一隻PERL程式
下一篇 09-雜湊

 

你可能感興趣的文章

自行撰寫syslog server建立資訊安全控管中心#4 -- 過濾條件設定 利用PERL將syslog收攏到資料庫的程式,過濾條件設定

[PERL] 前置if和後置if (if修飾子)的差別 perl的if可以拿來作為後置修飾子使用,此外還有一個unless像是if的相反,分析他們的差異

PERL一次讀取檔案所有內容的方法($/) perl可以使用slurp mode一次讀完檔案所有內容的方法及一些範例

[PERL] 03-條件式判斷 perl的條件式判斷

[PERL] Perl 不立即輸出的列印緩衝區問題 解決Perl 不立即輸出而是最後一次輸出的列印緩衝區問題

[PERL] 05-運算子 #1 PERL的運算子介紹,總共有21種

[PERL]] find 和 perl 的結合--大量檔案中文字的取代 利用PERL作大量的文件取代

自行撰寫syslog server建立資訊安全控管中心#3 -- 程式下載和安裝 利用PERL將syslog收攏到資料庫的程式,程式下載和安裝

[PERL] 檢查IP是否在某個網段內:matchcidr 檢查IP是否在某個網段內 matchcidr in perl

[PERL] 14-進階比對 #1--取回比對內容 perl的正規表達式進階比對

我有話要說


限制:留言最高字數1000字,超過部分會被截掉。請注意:留言不可帶有網址,會被濾掉。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

[jQuery] textarea 的取值和給值 HTML 的 TEXTAREA 標籤若要用 jquery 取值,不能使用 .text() 或 .html() ,使用 .

[HP DL380G7] 生效啟動第3,4片網卡/開啟或關閉內建的網卡 HP DL380G7 預設第3,4片網卡裝完系統後找不到,難道是壞了?要怎麼辦?

SELinux 常用指令和檔案 在Redhat系列中,Centos5以後加入了selinux,他並沒有這麼可怕,不必每次看到Selinux ,就想把他

PHP for sphinx 函式庫安裝 PECL/sphinx PHP>= 5.2.2 已經能原生支援 sphinx,可是預設的沒有裝,我們得自己裝才能用

[PHP] 檢查IP是否在某個網段內 mtachcidr 要檢查IP是否在某個網段內,要寫幾行?10行?5行? 不用,只要2行。以下是我寫的 code /** * matchCI