Perl關聯數組用法詳解
本文和大家重點討論一下Perl關聯數組的概念,Perl關聯數組的下標可以為任何簡單/標量值,訪問單個元素時以$符號打頭,下標用大括號圍起來。想了解Perl關聯數組的具體內容請看本文詳細介紹。
Perl關聯數組
一、Perl關聯數組變量的限制
在前面講的數組變量中,可以通過下標訪問其中的元素。例如,下列語句訪問數組@array的第三個元素:
$scalar=$array[2];
雖然數組很有用,但它們有一個顯著缺陷,即很難記住哪個元素存貯的什么內容。假如我們來寫一個程序計算某文件中首字母大寫的單詞出現的次數,用數組來實現就比較困難,程序代碼如下:
- 1:#!/usr/local/bin/perl
- 2:
- 3:while($inputline=){
- 4:while($inputline=~/\b[A-Z]\S+/g){
- 5:$word=$&;
- 6:$word=~s/[;.,:-]$//;#removepunctuation
- 7:for($count=1;$count<=@wordlist;
- 8:$count++){
- 9:$found=0;
- 10:if($wordlist[$count-1]eq$word){
- 11:$found=1;
- 12:$wordcount[$count-1]+=1;
- 13:last;
- 14:}
- 15:}
- 16:if($found==0){
- 17:$oldlength=@wordlist;
- 18:$wordlist[$oldlength]=$word;
- 19:$wordcount[$oldlength]=1;
- 20:}
- 21:}
- 22:}
- 23:print("Capitalizedwordsandnumberofoccurrences:\n");
- 24:for($count=1;$count<=@wordlist;$count++){
- 25:print("$wordlist[$count-1]:$wordcount[$count-1]\n");
- 26:}
運行結果如下:
- HereisalineofInput.
- ThisInputcontainssomeCapitalizedwords.
- ^D
- Capitalizedwordsandnumberofoccurrences:
- Here:1
- Input:2
- This:1
- Capitalized:1
這個程序每次從標準輸入文件讀一行文字,第四行起的循環匹配每行中首字母大寫的單詞,每找到一個循環一次,賦給簡單變量$word。在第六行中去掉標點后,查看該單詞是否曾出現過,7~15行中在@wordlist中挨個元素做此檢查,如果某個元素與$word相等,@wordcount中相應的元素就增加一個數。如果沒有出現過,即@wordlist中沒有元素與$word相等,16~20行給@wordlist和@wordcount增加一個新元素。
二、Perl關聯數組定義
正如你所看到的,使用數組元素產生了一些問題。首先,@wordlist中哪個元素對應著哪個單詞并不明顯;更糟的是,每讀進一個新單詞,程序必須檢查整個列表才能知道該單詞是否曾經出現過,當列表變得較大時,這是很耗費時間的。
這些問題產生的原因是數組元素通過數字下標訪問,為了解決這類問題,Perl定義了另一種數組,可以用任意簡單變量值來訪問其元素,這種數組叫做Perl關聯數組,也叫哈希表。
為了區分Perl關聯數組變量與普通的數組變量,Perl使用%作為其首字符,而數組變量以@打頭。與其它變量名一樣,%后的第一個字符必須為字母,后續字符可以為字母、數字或下劃線。
三、訪問Perl關聯數組的元素
Perl關聯數組的下標可以為任何簡單/標量值,訪問單個元素時以$符號打頭,下標用大括號圍起來。例如:
$fruit{"bananas"}
$number{3.14159}
$integer{-7}
簡單變量也可作為下標,如:
$fruit{$my_fruit}
四、增加元素
創建一個Perl關聯數組元素最簡單的方法是賦值,如語句$fruit{"bananas"}=1;把1賦給Perl關聯數組%fruit下標為bananas的元素,如果該元素不存在,則被創建,如果數組%fruit從未使用過,也被創建。
這一特性使得Perl關聯數組很容易用于計數。下面我們用Perl關聯數組改寫上面的程序,注意實現同樣的功能此程序簡化了許多。
- 1:#!/usr/local/bin/perl
- 2:
- 3:while($inputline=){
- 4:while($inputline=~/\b[A-Z]\S+/g){
- 5:$word=$&;
- 6:$word=~s/[;.,:-]$//;#removepunctuation
- 7:$wordlist{$word}+=1;
- 8:}
- 9:}
- 10:print("Capitalizedwordsandnumberofoccurrences:\n");
- 11:foreach$capword(keys(%wordlist)){
- 12:print("$capword:$wordlist{$capword}\n");
- 13:}
運行結果如下:
- HereisalineofInput.
- ThisInputcontainssomeCapitalizedwords.
- ^D
- Capitalizedwordsandnumberofoccurrences:
- This:1
- Input:2
- Here:1
- Capitalized:1
你可以看到,這次程序簡單多了,讀取輸入并存貯各單詞數目從20行減少到了7行。
本程序用Perl關聯數組%wordlist跟蹤首字母大寫的單詞,下標就用單詞本身,元素值為該單詞出現的次數。第11行使用了內嵌函數keys()。這個函數返回Perl關聯數組的下標列表,foreach語句就用此列表循環。
注:Perl關聯數組總是隨機存貯的,因此當你用keys()訪問其所有元素時,不保證元素以任何順序出現,特別值得一提的是,它們不會以被創建的順序出現。
要想控制Perl關聯數組元素出現的次序,可以用sort()函數對keys()返回值進行排列,如:
- foreach$capword(sortkeys(%wordlist)){
- print("$capword:$wordlist{$capword}\n");
- }
【編輯推薦】