IC入職新同學必備技能手冊#5 - Perl (3) - 奇特技巧
寫在前面:
這是Perl的倒數第二篇文章,蒐羅了工作環境中同事的指令碼,摘抄了一些我覺得有意思、奇特的程式碼技巧,用於實現一些非常實用的功能。
陣列去重(1):uniq 函式
use
List::MoreUtils
qw(uniq)
;
# 必須有這個引用
my
@arr
=
(
‘aa’
,
‘bb’
,
‘cc’
,
‘aa’
);
my
@unique_arr
=
uniq
@arr
;
“$_ \n”
foreach
@unique_arr
;
# 還記得$_ 麼?
#結果是
aa
bb
cc
陣列去重(2):grep 函式
uniq函式最好用,但是
需要環境裡安裝了CPAN支援
。下面使用自帶grep函式來完成去重。
my @arr = (‘aa’ , ‘bb’ , ‘cc’ , ‘aa’ );
my %temp_hash;
my @unique_arr = grep { ++$temp_hash{ $_ } < 2; } (@arr);
首先,grep函式的用法是 grep {篩選條件} (被遍歷的陣列)
注意,一個是花括號,一個是括號
grep的作用是,將符合“篩選條件”的陣列元素“挑”出來,重新組合一個新陣列
其次,++$temp_hash{ $_ } 又怎麼解讀?
$_ 表示迴圈遍歷@arr 陣列的每一個元素value, 例子中,一共4個元素,aa, bb, cc, aa
%temp_hash 是hash變數,但為啥後面又用$temp_hash?
不必糾結,對於hash變數,絕大部分情況是用 $hash_var{
key_name
} =
key_value
的形式來賦值的
++$temp_hash { $_ } 表示啥呢?(這裡我想用文字概括,試了,說不清楚,直接展開迴圈吧)
第一次迴圈:元素=aa, $temp_hash{ ‘aa’ } = 0,++後,$temp_hash{‘aa’} = 1
第二次迴圈:元素=bb, $temp_hash{ ‘bb’ } = 0, ++後,$temp_hash{‘bb’} = 1
第三次迴圈:元素=bb, $temp_hash{ ‘cc’ } = 0, ++後,$temp_hash{‘cc’} = 1
第四次迴圈
:元素=aa, $temp_hash{ ‘aa’ } = 1, ++後,$temp_hash{‘bb’} = 2
是不是在第四次迴圈時候,不符合grep的“篩選條件”了?那麼,這個多餘的aa就沒有入選新陣列。
至此!完成陣列去重
陣列排序:sort函式
網上有好多sort函式的講解,最好的版本永遠是官方文件。。以下為重點部分摘抄:
https://
perldoc。perl。org/functi
ons/sort。html
# 按字元(區分大小寫)升序
my @articles = sort {$a cmp $b} @arr;
# 倒序
my @articles = sort {$b cmp $a} @arr;
# 按數字升序
my @articles = sort {$a <=> $b} @arr;
# 倒序
my @articles = sort {$b <=> $a} @arr;
陣列的“再處理”:map函式
其實,“再處理”是我的理解 (post-processing),但不是最地道的解釋(可以叫對映?)。
舉個例子吧:有一個純數字的陣列,但是你想得到一個新陣列,新陣列的元素是原陣列中每個數的平方。
my @new_arr = map {$_ * $_} (@old_arr) ;
2。 再來個例子:有一個數組,裡面全是這個班的娃的名字(假設全小寫),我想篩選出名字的字母長度是4的,比如john, emma, mike 但jason就不行,那麼!
my @new_arr = map { $_ =~ /^\w{4}$/ ? $_ : ()} (@old_arr) ;
$_ 表示歷次迴圈中娃的名字
/^\w{4}$/ 是正則表示式,^表示字串起點錨,$表示字串終點錨,\w表示任意字元,\w{4}表示任意4個字元
xxx ? x : y 三目運算子就不解釋啦。
() 表示忽略這個元素,在新陣列中不對映它,說白了,丟掉它。
其實,這個例子可以用grep完成,用map有點累
my @new_arr = grep { $_ =~ /^\w{4}$/ } (@old_arr) ;
一行宣告多個變數
my ($var1, $var2, $var3, $var4);
my (@arr1, @arr2) ;
暫時看到這些,碰到不錯的,我會再加進來。